mesa/swrast: handle sRGB FBOs correctly (v2)
authorDave Airlie <airlied@redhat.com>
Mon, 10 Jan 2011 03:37:38 +0000 (13:37 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 10 Jan 2011 22:32:33 +0000 (08:32 +1000)
From reading EXT_texture_sRGB and EXT_framebuffer_sRGB and interactions
with FBO I've found that swrast is converting the sRGB values to linear for
blending when an sRGB texture is bound as an FBO. According to the spec
and further explained in the framebuffer_sRGB spec this behaviour is not
required unless the GL_FRAMEBUFFER_SRGB is enabled and the Visual/config
exposes GL_FRAMEBUFFER_SRGB_CAPABLE_EXT.

This patch fixes swrast to use a separate Fetch call for FBOs bound to
SRGB and avoid the conversions.

v2: export _mesa_get_texture_dimensions as per Brian's comments.

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/mesa/main/texfetch.c
src/mesa/main/texfetch.h
src/mesa/main/teximage.c
src/mesa/main/teximage.h
src/mesa/main/texrender.c

index 77bbc91795f23b0855b2166eb5af0cf90af9a141..113512090b269b9523e674f0c6a923399dd80e3f 100644 (file)
@@ -759,7 +759,7 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
 };
 
 
-static FetchTexelFuncF
+FetchTexelFuncF
 _mesa_get_texel_fetch_func(gl_format format, GLuint dims)
 {
 #ifdef DEBUG
index ef13bf27fec72cc8a113e3103128ab941fe10411..e78079ae5ab3e88d144a35f000f69feaaa34e379 100644 (file)
@@ -34,6 +34,9 @@
 extern StoreTexelFunc
 _mesa_get_texel_store_func(gl_format format);
 
+extern FetchTexelFuncF
+_mesa_get_texel_fetch_func(gl_format format, GLuint dims);
+
 extern void
 _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims);
 
index 1e8626c7346e381f552b262d6563332b2cad626f..47d509396a788857a4e2a4d3416b4053cb4229fb 100644 (file)
@@ -932,8 +932,8 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
 /**
  * Return number of dimensions per mipmap level for the given texture target.
  */
-static GLint
-get_texture_dimensions(GLenum target)
+GLint
+_mesa_get_texture_dimensions(GLenum target)
 {
    switch (target) {
    case GL_TEXTURE_1D:
@@ -1158,7 +1158,7 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
 
    img->TexFormat = format;
 
-   dims = get_texture_dimensions(target);
+   dims = _mesa_get_texture_dimensions(target);
 
    _mesa_set_fetch_functions(img, dims);
 }
index 5bb9d492e932f8680a934e82b5742d5fa10ddf93..bb5509e5be679d67f376a270250ca0184d9f6baf 100644 (file)
@@ -126,6 +126,8 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
 extern GLuint
 _mesa_tex_target_to_face(GLenum target);
 
+extern GLint
+_mesa_get_texture_dimensions(GLenum target);
 
 /**
  * Lock a texture for updating.  See also _mesa_lock_context_textures().
index 8961b926487b9e8d3be1ecd18c687c54f2b36980..e7cb18a87a6734c8c7caf638c47e5a8d136b4ea0 100644 (file)
@@ -20,6 +20,7 @@ struct texture_renderbuffer
    struct gl_renderbuffer Base;   /**< Base class object */
    struct gl_texture_image *TexImage;
    StoreTexelFunc Store;
+   FetchTexelFuncF Fetchf;
    GLint Yoffset;                 /**< Layer for 1D array textures. */
    GLint Zoffset;                 /**< Layer for 2D array textures, or slice
                                   * for 3D textures
@@ -48,7 +49,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
       GLchan *rgbaOut = (GLchan *) values;
       for (i = 0; i < count; i++) {
          GLfloat rgba[4];
-         trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, rgba);
+         trb->Fetchf(trb->TexImage, x + i, y, z, rgba);
          UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba);
       }
    }
@@ -56,7 +57,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
       GLushort *zValues = (GLushort *) values;
       for (i = 0; i < count; i++) {
          GLfloat flt;
-         trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
+         trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
          zValues[i] = (GLushort) (flt * 0xffff);
       }
    }
@@ -67,7 +68,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
       */
       for (i = 0; i < count; i++) {
          GLfloat flt;
-         trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
+         trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
 #if 0
          /* this should work, but doesn't (overflow due to low precision) */
          zValues[i] = (GLuint) (flt * scale);
@@ -81,7 +82,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
       GLuint *zValues = (GLuint *) values;
       for (i = 0; i < count; i++) {
          GLfloat flt;
-         trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
+         trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
          zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
       }
    }
@@ -89,7 +90,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
       GLuint *zValues = (GLuint *) values;
       for (i = 0; i < count; i++) {
          GLfloat flt;
-         trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
+         trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
          zValues[i] = (GLuint) (flt * 0xffffff);
       }
    }
@@ -112,7 +113,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
       GLchan *rgbaOut = (GLchan *) values;
       for (i = 0; i < count; i++) {
          GLfloat rgba[4];
-         trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
+         trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
                                    z, rgba);
          UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba);
       }
@@ -121,7 +122,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
       GLushort *zValues = (GLushort *) values;
       for (i = 0; i < count; i++) {
          GLfloat flt;
-         trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
+         trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
                                    z, &flt);
          zValues[i] = (GLushort) (flt * 0xffff);
       }
@@ -130,7 +131,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
       GLuint *zValues = (GLuint *) values;
       for (i = 0; i < count; i++) {
          GLfloat flt;
-         trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
+         trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
                                    z, &flt);
 #if 0
          zValues[i] = (GLuint) (flt * 0xffffffff);
@@ -143,7 +144,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
       GLuint *zValues = (GLuint *) values;
       for (i = 0; i < count; i++) {
          GLfloat flt;
-         trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
+         trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
                                    z, &flt);
          zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
       }
@@ -152,7 +153,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
       GLuint *zValues = (GLuint *) values;
       for (i = 0; i < count; i++) {
          GLfloat flt;
-         trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
+         trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
                                    z, &flt);
          zValues[i] = (GLuint) (flt * 0xffffff);
       }
@@ -517,8 +518,6 @@ wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
    _mesa_reference_renderbuffer(&att->Renderbuffer, &(trb->Base));
 }
 
-
-
 /**
  * Update the renderbuffer wrapper for rendering to a texture.
  * For example, update the width, height of the RB based on the texture size,
@@ -542,6 +541,8 @@ update_wrapper(struct gl_context *ctx, const struct gl_renderbuffer_attachment *
       trb->Store = store_nop;
    }
 
+   trb->Fetchf = trb->TexImage->FetchTexelf;
+
    if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {
       trb->Yoffset = att->Zoffset;
       trb->Zoffset = 0;
@@ -582,6 +583,17 @@ update_wrapper(struct gl_context *ctx, const struct gl_renderbuffer_attachment *
       trb->Base.DataType = GL_UNSIGNED_INT;
       trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
       break;
+   /* SRGB formats pre EXT_framebuffer_sRGB don't do sRGB translations on FBO readback */
+   case MESA_FORMAT_SRGB8:
+      trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGB888, _mesa_get_texture_dimensions(att->Texture->Target));
+      trb->Base.DataType = CHAN_TYPE;
+      trb->Base._BaseFormat = GL_RGBA;
+      break;
+   case MESA_FORMAT_SRGBA8:
+      trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGBA8888, _mesa_get_texture_dimensions(att->Texture->Target));
+      trb->Base.DataType = CHAN_TYPE;
+      trb->Base._BaseFormat = GL_RGBA;
+      break;
    default:
       trb->Base.DataType = CHAN_TYPE;
       trb->Base._BaseFormat = GL_RGBA;