No subject


Sun Jan 9 19:24:33 PST 2011


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.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/mesa/main/texfetch.c  |    2 +-
 src/mesa/main/texfetch.h  |    3 ++
 src/mesa/main/texrender.c |   60 ++++++++++++++++++++++++++++++++++++--------
 3 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/src/mesa/main/texfetch.c b/src/mesa/main/texfetch.c
index 77bbc91..1135120 100644
--- a/src/mesa/main/texfetch.c
+++ b/src/mesa/main/texfetch.c
@@ -759,7 +759,7 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
 };
 
 
-static FetchTexelFuncF
+FetchTexelFuncF
 _mesa_get_texel_fetch_func(gl_format format, GLuint dims)
 {
 #ifdef DEBUG
diff --git a/src/mesa/main/texfetch.h b/src/mesa/main/texfetch.h
index ef13bf2..e78079a 100644
--- a/src/mesa/main/texfetch.h
+++ b/src/mesa/main/texfetch.h
@@ -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);
 
diff --git a/src/mesa/main/texrender.c b/src/mesa/main/texrender.c
index 8961b92..1001444 100644
--- a/src/mesa/main/texrender.c
+++ b/src/mesa/main/texrender.c
@@ -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,7 +518,31 @@ wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
    _mesa_reference_renderbuffer(&att->Renderbuffer, &(trb->Base));
 }
 
-
+static GLuint
+get_texture_dims(GLenum target)
+{
+   switch (target) {
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_1D_ARRAY_EXT:
+      return 1;
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_CUBE_MAP_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+   case GL_TEXTURE_RECTANGLE_NV:
+   case GL_TEXTURE_2D_ARRAY_EXT:
+      return 2;
+   case GL_TEXTURE_3D:
+      return 3;
+   default:
+      assert(0 && "invalid texture target in get_texture_dims()");
+      return 1;
+   }
+}
 
 /**
  * Update the renderbuffer wrapper for rendering to a texture.
@@ -542,6 +567,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 +609,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, get_texture_dims(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, get_texture_dims(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;
-- 
1.7.1



More information about the mesa-dev mailing list