st/mesa: ensure that all pixel paths operation on linear RGB data, not sRGB
authorBrian Paul <brianp@vmware.com>
Sun, 23 Jan 2011 01:28:20 +0000 (18:28 -0700)
committerBrian Paul <brianp@vmware.com>
Sun, 23 Jan 2011 01:33:35 +0000 (18:33 -0700)
Before, we were converting between linear/sRGB in glReadPixels,
glDrawPixels, glAccum, etc if the renderbuffer was an sRGB texture.
Those all need to operate on pixel values as-is without conversion.

Also, when setting up render-to-texture, if the texture is sRGB the
pipe_surface view must be linear RGB.  This will change when we
support GL_ARB_framebuffer_sRGB.

This fixes http://bugs.freedesktop.org/show_bug.cgi?id=33353

src/mesa/state_tracker/st_cb_accum.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_readpixels.c
src/mesa/state_tracker/st_cb_texture.c

index 35921f4f614dfd9156a4b1e53c525c34e96bd664..3e01c440bdad0f8a700b6ab90c115dfa28f64216 100644 (file)
@@ -42,6 +42,7 @@
 #include "st_texture.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
+#include "util/u_format.h"
 #include "util/u_inlines.h"
 #include "util/u_tile.h"
 
@@ -146,7 +147,9 @@ accum_accum(struct st_context *st, GLfloat value,
 
    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
 
-   pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
+   pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
+                             util_format_linear(color_strb->texture->format),
+                             buf);
 
    switch (acc_strb->format) {
    case PIPE_FORMAT_R16G16B16A16_SNORM:
@@ -183,7 +186,6 @@ accum_load(struct st_context *st, GLfloat value,
    GLubyte *data = acc_strb->data;
    GLfloat *buf;
 
-
    if (ST_DEBUG & DEBUG_FALLBACK)
       debug_printf("%s: fallback processing\n", __FUNCTION__);
 
@@ -194,7 +196,9 @@ accum_load(struct st_context *st, GLfloat value,
 
    buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
 
-   pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
+   pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
+                             util_format_linear(color_strb->texture->format),
+                             buf);
 
    switch (acc_strb->format) {
    case PIPE_FORMAT_R16G16B16A16_SNORM:
@@ -232,6 +236,7 @@ accum_return(struct gl_context *ctx, GLfloat value,
    size_t stride = acc_strb->stride;
    const GLubyte *data = acc_strb->data;
    GLfloat *buf;
+   enum pipe_format format = util_format_linear(color_strb->texture->format);
 
    if (ST_DEBUG & DEBUG_FALLBACK)
       debug_printf("%s: fallback processing\n", __FUNCTION__);
@@ -250,7 +255,8 @@ accum_return(struct gl_context *ctx, GLfloat value,
                                    width, height);
 
    if (usage & PIPE_TRANSFER_READ)
-      pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
+      pipe_get_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
+                                format, buf);
 
    switch (acc_strb->format) {
    case PIPE_FORMAT_R16G16B16A16_SNORM:
@@ -279,7 +285,8 @@ accum_return(struct gl_context *ctx, GLfloat value,
       _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()");
    }
 
-   pipe_put_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
+   pipe_put_tile_rgba_format(pipe, color_trans, 0, 0, width, height,
+                             format, buf);
 
    free(buf);
    pipe->transfer_destroy(pipe, color_trans);
index d128ff98f02d0da7e4b73501478017ffb6c85a67..ee610fe6152506adf4c4e7240506e05c0cc97618 100644 (file)
@@ -1302,9 +1302,13 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       if (type == GL_COLOR) {
          /* alternate path using get/put_tile() */
          GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
-         pipe_get_tile_rgba(pipe, ptRead, readX, readY, readW, readH, buf);
-         pipe_put_tile_rgba(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
-                            readW, readH, buf);
+         enum pipe_format readFormat, drawFormat;
+         readFormat = util_format_linear(rbRead->texture->format);
+         drawFormat = util_format_linear(pt->format);
+         pipe_get_tile_rgba_format(pipe, ptRead, readX, readY, readW, readH,
+                                   readFormat, buf);
+         pipe_put_tile_rgba_format(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
+                                   readW, readH, drawFormat, buf);
          free(buf);
       }
       else {
index 0c7641f86236266dd2904b944d9d22a62f3f8f06..52464707eaea0ea3008bb123ac8a6ffccac04bad 100644 (file)
@@ -390,7 +390,7 @@ st_render_texture(struct gl_context *ctx,
 
    /* new surface for rendering into the texture */
    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
-   surf_tmpl.format = strb->texture->format;
+   surf_tmpl.format = util_format_linear(strb->texture->format);
    surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
    surf_tmpl.u.tex.level = strb->rtt_level;
    surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
index 0507be745783be12d689ce7c19eabe5d01876a63..4689a0032b72145cca033f7ad67835f6a2d30497 100644 (file)
@@ -41,6 +41,7 @@
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
+#include "util/u_format.h"
 #include "util/u_inlines.h"
 #include "util/u_tile.h"
 
@@ -336,6 +337,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
    struct st_renderbuffer *strb;
    struct gl_pixelstore_attrib clippedPacking = *pack;
    struct pipe_transfer *trans;
+   enum pipe_format pformat;
 
    assert(ctx->ReadBuffer->Width > 0);
 
@@ -421,6 +423,9 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
       yStep = 1;
    }
 
+   /* possibly convert sRGB format to linear RGB format */
+   pformat = util_format_linear(trans->resource->format);
+
    if (ST_DEBUG & DEBUG_FALLBACK)
       debug_printf("%s: fallback processing\n", __FUNCTION__);
 
@@ -435,8 +440,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
       const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
                                                      format, type);
 
-      if (trans->resource->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
-          trans->resource->format == PIPE_FORMAT_Z24X8_UNORM) {
+      if (pformat == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
+          pformat == PIPE_FORMAT_Z24X8_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH];
@@ -467,8 +472,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
             }
          }
       }
-      else if (trans->resource->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
-               trans->resource->format == PIPE_FORMAT_X8Z24_UNORM) {
+      else if (pformat == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
+               pformat == PIPE_FORMAT_X8Z24_UNORM) {
          if (format == GL_DEPTH_COMPONENT) {
             for (i = 0; i < height; i++) {
                GLuint ztemp[MAX_WIDTH];
@@ -494,7 +499,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
             }
          }
       }
-      else if (trans->resource->format == PIPE_FORMAT_Z16_UNORM) {
+      else if (pformat == PIPE_FORMAT_Z16_UNORM) {
          for (i = 0; i < height; i++) {
             GLushort ztemp[MAX_WIDTH];
             GLfloat zfloat[MAX_WIDTH];
@@ -509,7 +514,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
             dst += dstStride;
          }
       }
-      else if (trans->resource->format == PIPE_FORMAT_Z32_UNORM) {
+      else if (pformat == PIPE_FORMAT_Z32_UNORM) {
          for (i = 0; i < height; i++) {
             GLuint ztemp[MAX_WIDTH];
             GLfloat zfloat[MAX_WIDTH];
@@ -528,7 +533,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
          /* RGBA format */
          /* Do a row at a time to flip image data vertically */
          for (i = 0; i < height; i++) {
-            pipe_get_tile_rgba(pipe, trans, 0, y, width, 1, df);
+            pipe_get_tile_rgba_format(pipe, trans, 0, y, width, 1,
+                                      pformat, df);
             y += yStep;
             df += dfStride;
             if (!dfStride) {
index 09a10ba58196d121fb6c48013094043a16b30d82..795910734bf6314d8c38b56dc7c46fd3cb00041c 100644 (file)
@@ -918,6 +918,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
    else {
       /* format translation via floats */
       GLuint row;
+      enum pipe_format format = util_format_linear(dst_texture->format);
       for (row = 0; row < height; row++) {
          const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */
          GLfloat rgba[4 * MAX_WIDTH];
@@ -928,7 +929,8 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
             debug_printf("%s: fallback format translation\n", __FUNCTION__);
 
          /* get float[4] rgba row from surface */
-         pipe_get_tile_rgba(pipe, tex_xfer, 0, row, width, 1, rgba);
+         pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1,
+                                   format, rgba);
 
          _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
                                     type, dest, &ctx->Pack, transferOps);
@@ -1387,7 +1389,9 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
          /* XXX this usually involves a lot of int/float conversion.
           * try to avoid that someday.
           */
-         pipe_get_tile_rgba(pipe, src_trans, 0, 0, width, height, tempSrc);
+         pipe_get_tile_rgba_format(pipe, src_trans, 0, 0, width, height,
+                                   util_format_linear(strb->texture->format),
+                                   tempSrc);
 
          /* Store into texture memory.
           * Note that this does some special things such as pixel transfer