[Mesa-dev] [PATCH 6/6] mesa/main: Use the RGB <-> sRGB conversion functions in libmesautil

Jason Ekstrand jason at jlekstrand.net
Thu Jul 24 17:15:23 PDT 2014


Signed-off-by: Jason Ekstrand <jason.ekstrand at intel.com>
---
 src/mesa/main/format_pack.c      | 102 ++++++++++++++-------------------------
 src/mesa/main/format_unpack.c    |  69 ++++++++------------------
 src/mesa/main/format_unpack.h    |   3 --
 src/mesa/main/texcompress_etc.c  |  19 ++++----
 src/mesa/main/texcompress_s3tc.c |  25 +++++-----
 src/mesa/swrast/s_texfetch.c     |  30 +-----------
 src/mesa/swrast/s_texfetch_tmp.h |  34 ++++++-------
 src/util/format_srgb.h           |  15 ++++++
 8 files changed, 112 insertions(+), 185 deletions(-)

diff --git a/src/mesa/main/format_pack.c b/src/mesa/main/format_pack.c
index c97c052..6cbf859 100644
--- a/src/mesa/main/format_pack.c
+++ b/src/mesa/main/format_pack.c
@@ -41,6 +41,7 @@
 #include "macros.h"
 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
+#include "util/format_srgb.h"
 
 
 /** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */
@@ -58,39 +59,6 @@ typedef void (*pack_float_rgba_row_func)(GLuint n,
                                          const GLfloat src[][4], void *dst);
 
 
-
-static inline GLfloat
-linear_to_srgb(GLfloat cl)
-{
-   if (cl < 0.0f)
-      return 0.0f;
-   else if (cl < 0.0031308f)
-      return 12.92f * cl;
-   else if (cl < 1.0f)
-      return 1.055f * powf(cl, 0.41666f) - 0.055f;
-   else
-      return 1.0f;
-}
-
-
-static inline GLubyte
-linear_float_to_srgb_ubyte(GLfloat cl)
-{
-   GLubyte res = FLOAT_TO_UBYTE(linear_to_srgb(cl));
-   return res;
-}
-
-
-static inline GLubyte
-linear_ubyte_to_srgb_ubyte(GLubyte cl)
-{
-   GLubyte res = FLOAT_TO_UBYTE(linear_to_srgb(cl / 255.0f));
-   return res;
-}
-
-
-
-
 /*
  * MESA_FORMAT_A8B8G8R8_UNORM
  */
@@ -1043,18 +1011,18 @@ static void
 pack_ubyte_BGR_SRGB8(const GLubyte src[4], void *dst)
 {
    GLubyte *d = ((GLubyte *) dst);
-   d[2] = linear_ubyte_to_srgb_ubyte(src[RCOMP]);
-   d[1] = linear_ubyte_to_srgb_ubyte(src[GCOMP]);
-   d[0] = linear_ubyte_to_srgb_ubyte(src[BCOMP]);
+   d[2] = util_format_linear_to_srgb_8unorm(src[RCOMP]);
+   d[1] = util_format_linear_to_srgb_8unorm(src[GCOMP]);
+   d[0] = util_format_linear_to_srgb_8unorm(src[BCOMP]);
 }
 
 static void
 pack_float_BGR_SRGB8(const GLfloat src[4], void *dst)
 {
    GLubyte *d = ((GLubyte *) dst);
-   d[2] = linear_float_to_srgb_ubyte(src[RCOMP]);
-   d[1] = linear_float_to_srgb_ubyte(src[GCOMP]);
-   d[0] = linear_float_to_srgb_ubyte(src[BCOMP]);
+   d[2] = util_format_linear_float_to_srgb_8unorm(src[RCOMP]);
+   d[1] = util_format_linear_float_to_srgb_8unorm(src[GCOMP]);
+   d[0] = util_format_linear_float_to_srgb_8unorm(src[BCOMP]);
 }
 
 
@@ -1064,9 +1032,9 @@ static void
 pack_ubyte_A8B8G8R8_SRGB(const GLubyte src[4], void *dst)
 {
    GLuint *d = ((GLuint *) dst);
-   GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]);
-   GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]);
-   GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]);
+   GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]);
+   GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]);
+   GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]);
    *d = PACK_COLOR_8888(r, g, b, src[ACOMP]);
 }
 
@@ -1075,9 +1043,9 @@ pack_float_A8B8G8R8_SRGB(const GLfloat src[4], void *dst)
 {
    GLuint *d = ((GLuint *) dst);
    GLubyte r, g, b, a;
-   r = linear_float_to_srgb_ubyte(src[RCOMP]);
-   g = linear_float_to_srgb_ubyte(src[GCOMP]);
-   b = linear_float_to_srgb_ubyte(src[BCOMP]);
+   r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]);
+   g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]);
+   b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]);
    UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]);
    *d = PACK_COLOR_8888(r, g, b, a);
 }
@@ -1089,9 +1057,9 @@ static void
 pack_ubyte_B8G8R8A8_SRGB(const GLubyte src[4], void *dst)
 {
    GLuint *d = ((GLuint *) dst);
-   GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]);
-   GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]);
-   GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]);
+   GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]);
+   GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]);
+   GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]);
    *d = PACK_COLOR_8888(src[ACOMP], r, g, b);
 }
 
@@ -1100,9 +1068,9 @@ pack_float_B8G8R8A8_SRGB(const GLfloat src[4], void *dst)
 {
    GLuint *d = ((GLuint *) dst);
    GLubyte r, g, b, a;
-   r = linear_float_to_srgb_ubyte(src[RCOMP]);
-   g = linear_float_to_srgb_ubyte(src[GCOMP]);
-   b = linear_float_to_srgb_ubyte(src[BCOMP]);
+   r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]);
+   g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]);
+   b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]);
    UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]);
    *d = PACK_COLOR_8888(a, r, g, b);
 }
@@ -1114,9 +1082,9 @@ static void
 pack_ubyte_R8G8B8A8_SRGB(const GLubyte src[4], void *dst)
 {
    GLuint *d = ((GLuint *) dst);
-   GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]);
-   GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]);
-   GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]);
+   GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]);
+   GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]);
+   GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]);
    *d = PACK_COLOR_8888(src[ACOMP], b, g, r);
 }
 
@@ -1125,9 +1093,9 @@ pack_float_R8G8B8A8_SRGB(const GLfloat src[4], void *dst)
 {
    GLuint *d = ((GLuint *) dst);
    GLubyte r, g, b, a;
-   r = linear_float_to_srgb_ubyte(src[RCOMP]);
-   g = linear_float_to_srgb_ubyte(src[GCOMP]);
-   b = linear_float_to_srgb_ubyte(src[BCOMP]);
+   r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]);
+   g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]);
+   b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]);
    UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]);
    *d = PACK_COLOR_8888(a, b, g, r);
 }
@@ -1139,14 +1107,14 @@ static void
 pack_ubyte_L_SRGB8(const GLubyte src[4], void *dst)
 {
    GLubyte *d = ((GLubyte *) dst);
-   *d = linear_ubyte_to_srgb_ubyte(src[RCOMP]);
+   *d = util_format_linear_to_srgb_8unorm(src[RCOMP]);
 }
 
 static void
 pack_float_L_SRGB8(const GLfloat src[4], void *dst)
 {
    GLubyte *d = ((GLubyte *) dst);
-   GLubyte l = linear_float_to_srgb_ubyte(src[RCOMP]);
+   GLubyte l = util_format_linear_float_to_srgb_8unorm(src[RCOMP]);
    *d = l;
 }
 
@@ -1157,7 +1125,7 @@ static void
 pack_ubyte_L8A8_SRGB(const GLubyte src[4], void *dst)
 {
    GLushort *d = ((GLushort *) dst);
-   GLubyte l = linear_ubyte_to_srgb_ubyte(src[RCOMP]);
+   GLubyte l = util_format_linear_to_srgb_8unorm(src[RCOMP]);
    *d = PACK_COLOR_88(src[ACOMP], l);
 }
 
@@ -1165,7 +1133,7 @@ static void
 pack_float_L8A8_SRGB(const GLfloat src[4], void *dst)
 {
    GLushort *d = ((GLushort *) dst);
-   GLubyte a, l = linear_float_to_srgb_ubyte(src[RCOMP]);
+   GLubyte a, l = util_format_linear_float_to_srgb_8unorm(src[RCOMP]);
    CLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]);
    *d = PACK_COLOR_88(a, l);
 }
@@ -1742,9 +1710,9 @@ static void
 pack_float_R8G8B8X8_SRGB(const GLfloat src[4], void *dst)
 {
    GLuint *d = (GLuint *) dst;
-   GLubyte r = linear_float_to_srgb_ubyte(src[RCOMP]);
-   GLubyte g = linear_float_to_srgb_ubyte(src[GCOMP]);
-   GLubyte b = linear_float_to_srgb_ubyte(src[BCOMP]);
+   GLubyte r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]);
+   GLubyte g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]);
+   GLubyte b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]);
    *d = PACK_COLOR_8888(127, b, g, r);
 }
 
@@ -1892,9 +1860,9 @@ static void
 pack_float_B8G8R8X8_SRGB(const GLfloat src[4], void *dst)
 {
    GLuint *d = (GLuint *) dst;
-   GLubyte r = linear_float_to_srgb_ubyte(src[RCOMP]);
-   GLubyte g = linear_float_to_srgb_ubyte(src[GCOMP]);
-   GLubyte b = linear_float_to_srgb_ubyte(src[BCOMP]);
+   GLubyte r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]);
+   GLubyte g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]);
+   GLubyte b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]);
    *d = PACK_COLOR_8888(127, r, g, b);
 }
 
diff --git a/src/mesa/main/format_unpack.c b/src/mesa/main/format_unpack.c
index ad5ea4c..b84ed02 100644
--- a/src/mesa/main/format_unpack.c
+++ b/src/mesa/main/format_unpack.c
@@ -28,6 +28,7 @@
 #include "macros.h"
 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
+#include "util/format_srgb.h"
 
 
 /** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */
@@ -53,34 +54,6 @@ struct z32f_x24s8
 #define EXPAND_6_8(X)  ( ((X) << 2) | ((X) >> 4) )
 
 
-/**
- * Convert an 8-bit sRGB value from non-linear space to a
- * linear RGB value in [0, 1].
- * Implemented with a 256-entry lookup table.
- */
-GLfloat
-_mesa_nonlinear_to_linear(GLubyte cs8)
-{
-   static GLfloat table[256];
-   static GLboolean tableReady = GL_FALSE;
-   if (!tableReady) {
-      /* compute lookup table now */
-      GLuint i;
-      for (i = 0; i < 256; i++) {
-         const GLfloat cs = UBYTE_TO_FLOAT(i);
-         if (cs <= 0.04045) {
-            table[i] = cs / 12.92f;
-         }
-         else {
-            table[i] = (GLfloat) pow((cs + 0.055) / 1.055, 2.4);
-         }
-      }
-      tableReady = GL_TRUE;
-   }
-   return table[cs8];
-}
-
-
 /**********************************************************************/
 /*  Unpack, returning GLfloat colors                                  */
 /**********************************************************************/
@@ -763,9 +736,9 @@ unpack_BGR_SRGB8(const void *src, GLfloat dst[][4], GLuint n)
    const GLubyte *s = (const GLubyte *) src;
    GLuint i;
    for (i = 0; i < n; i++) {
-      dst[i][RCOMP] = _mesa_nonlinear_to_linear(s[i*3+2]);
-      dst[i][GCOMP] = _mesa_nonlinear_to_linear(s[i*3+1]);
-      dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i*3+0]);
+      dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+2]);
+      dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+1]);
+      dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+0]);
       dst[i][ACOMP] = 1.0F;
    }
 }
@@ -776,9 +749,9 @@ unpack_A8B8G8R8_SRGB(const void *src, GLfloat dst[][4], GLuint n)
    const GLuint *s = ((const GLuint *) src);
    GLuint i;
    for (i = 0; i < n; i++) {
-      dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 24) );
-      dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff );
-      dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] >>  8) & 0xff );
+      dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 24) );
+      dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff );
+      dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >>  8) & 0xff );
       dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); /* linear! */
    }
 }
@@ -789,9 +762,9 @@ unpack_B8G8R8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n)
    const GLuint *s = ((const GLuint *) src);
    GLuint i;
    for (i = 0; i < n; i++) {
-      dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff );
-      dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >>  8) & 0xff );
-      dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i]      ) & 0xff );
+      dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff );
+      dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >>  8) & 0xff );
+      dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i]      ) & 0xff );
       dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */
    }
 }
@@ -802,9 +775,9 @@ unpack_R8G8B8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n)
    const GLuint *s = ((const GLuint *) src);
    GLuint i;
    for (i = 0; i < n; i++) {
-      dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i]      ) & 0xff );
-      dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >>  8) & 0xff );
-      dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff );
+      dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i]      ) & 0xff );
+      dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >>  8) & 0xff );
+      dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff );
       dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */
    }
 }
@@ -817,7 +790,7 @@ unpack_L_SRGB8(const void *src, GLfloat dst[][4], GLuint n)
    for (i = 0; i < n; i++) {
       dst[i][RCOMP] = 
       dst[i][GCOMP] = 
-      dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i]);
+      dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i]);
       dst[i][ACOMP] = 1.0F;
    }
 }
@@ -830,7 +803,7 @@ unpack_L8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n)
    for (i = 0; i < n; i++) {
       dst[i][RCOMP] =
       dst[i][GCOMP] =
-      dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i] & 0xff);
+      dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i] & 0xff);
       dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i] >> 8); /* linear! */
    }
 }
@@ -2124,9 +2097,9 @@ unpack_R8G8B8X8_SRGB(const void *src, GLfloat dst[][4], GLuint n)
    const GLuint *s = ((const GLuint *) src);
    GLuint i;
    for (i = 0; i < n; i++) {
-      dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i]      ) & 0xff );
-      dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >>  8) & 0xff );
-      dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff );
+      dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i]      ) & 0xff );
+      dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >>  8) & 0xff );
+      dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff );
       dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */
    }
 }
@@ -2319,9 +2292,9 @@ unpack_B8G8R8X8_SRGB(const void *src, GLfloat dst[][4], GLuint n)
    const GLuint *s = ((const GLuint *) src);
    GLuint i;
    for (i = 0; i < n; i++) {
-      dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff );
-      dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >>  8) & 0xff );
-      dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i]      ) & 0xff );
+      dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff );
+      dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >>  8) & 0xff );
+      dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i]      ) & 0xff );
       dst[i][ACOMP] = 1.0F;
    }
 }
diff --git a/src/mesa/main/format_unpack.h b/src/mesa/main/format_unpack.h
index 51f97df..eba3c66 100644
--- a/src/mesa/main/format_unpack.h
+++ b/src/mesa/main/format_unpack.h
@@ -25,9 +25,6 @@
 #ifndef FORMAT_UNPACK_H
 #define FORMAT_UNPACK_H
 
-extern GLfloat
-_mesa_nonlinear_to_linear(GLubyte cs8);
-
 extern void
 _mesa_unpack_rgba_row(mesa_format format, GLuint n,
                       const void *src, GLfloat dst[][4]);
diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c
index ae973b0..98b4fe2 100644
--- a/src/mesa/main/texcompress_etc.c
+++ b/src/mesa/main/texcompress_etc.c
@@ -43,6 +43,7 @@
 #include "texstore.h"
 #include "macros.h"
 #include "format_unpack.h"
+#include "util/format_srgb.h"
 
 
 struct etc2_block {
@@ -1307,9 +1308,9 @@ fetch_etc2_srgb8(const GLubyte *map,
    etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
                          false /* punchthrough_alpha */);
 
-   texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
-   texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
-   texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]);
    texel[ACOMP] = 1.0f;
 }
 
@@ -1345,9 +1346,9 @@ fetch_etc2_srgb8_alpha8_eac(const GLubyte *map,
    etc2_rgba8_parse_block(&block, src);
    etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
 
-   texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
-   texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
-   texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]);
    texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
 }
 
@@ -1473,9 +1474,9 @@ fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte *map,
                          true /* punchthrough alpha */);
    etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
                          true /* punchthrough alpha */);
-   texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
-   texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
-   texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]);
    texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
 }
 
diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c
index 894c46d..5b275ef 100644
--- a/src/mesa/main/texcompress_s3tc.c
+++ b/src/mesa/main/texcompress_s3tc.c
@@ -44,6 +44,7 @@
 #include "texcompress_s3tc.h"
 #include "texstore.h"
 #include "format_unpack.h"
+#include "util/format_srgb.h"
 
 
 #if defined(_WIN32) || defined(WIN32)
@@ -419,9 +420,9 @@ fetch_srgb_dxt1(const GLubyte *map,
    if (fetch_ext_rgb_dxt1) {
       GLubyte tex[4];
       fetch_ext_rgb_dxt1(rowStride, map, i, j, tex);
-      texel[RCOMP] = _mesa_nonlinear_to_linear(tex[RCOMP]);
-      texel[GCOMP] = _mesa_nonlinear_to_linear(tex[GCOMP]);
-      texel[BCOMP] = _mesa_nonlinear_to_linear(tex[BCOMP]);
+      texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+      texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+      texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
       texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
    }
    else {
@@ -436,9 +437,9 @@ fetch_srgba_dxt1(const GLubyte *map,
    if (fetch_ext_rgba_dxt1) {
       GLubyte tex[4];
       fetch_ext_rgba_dxt1(rowStride, map, i, j, tex);
-      texel[RCOMP] = _mesa_nonlinear_to_linear(tex[RCOMP]);
-      texel[GCOMP] = _mesa_nonlinear_to_linear(tex[GCOMP]);
-      texel[BCOMP] = _mesa_nonlinear_to_linear(tex[BCOMP]);
+      texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+      texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+      texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
       texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
    }
    else {
@@ -453,9 +454,9 @@ fetch_srgba_dxt3(const GLubyte *map,
    if (fetch_ext_rgba_dxt3) {
       GLubyte tex[4];
       fetch_ext_rgba_dxt3(rowStride, map, i, j, tex);
-      texel[RCOMP] = _mesa_nonlinear_to_linear(tex[RCOMP]);
-      texel[GCOMP] = _mesa_nonlinear_to_linear(tex[GCOMP]);
-      texel[BCOMP] = _mesa_nonlinear_to_linear(tex[BCOMP]);
+      texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+      texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+      texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
       texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
    }
    else {
@@ -470,9 +471,9 @@ fetch_srgba_dxt5(const GLubyte *map,
    if (fetch_ext_rgba_dxt5) {
       GLubyte tex[4];
       fetch_ext_rgba_dxt5(rowStride, map, i, j, tex);
-      texel[RCOMP] = _mesa_nonlinear_to_linear(tex[RCOMP]);
-      texel[GCOMP] = _mesa_nonlinear_to_linear(tex[GCOMP]);
-      texel[BCOMP] = _mesa_nonlinear_to_linear(tex[BCOMP]);
+      texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
+      texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
+      texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
       texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
    }
    else {
diff --git a/src/mesa/swrast/s_texfetch.c b/src/mesa/swrast/s_texfetch.c
index e508368..aef0232 100644
--- a/src/mesa/swrast/s_texfetch.c
+++ b/src/mesa/swrast/s_texfetch.c
@@ -46,35 +46,7 @@
 #include "s_texfetch.h"
 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
-
-
-/**
- * Convert an 8-bit sRGB value from non-linear space to a
- * linear RGB value in [0, 1].
- * Implemented with a 256-entry lookup table.
- */
-static inline GLfloat
-nonlinear_to_linear(GLubyte cs8)
-{
-   static GLfloat table[256];
-   static GLboolean tableReady = GL_FALSE;
-   if (!tableReady) {
-      /* compute lookup table now */
-      GLuint i;
-      for (i = 0; i < 256; i++) {
-         const GLfloat cs = UBYTE_TO_FLOAT(i);
-         if (cs <= 0.04045) {
-            table[i] = cs / 12.92f;
-         }
-         else {
-            table[i] = (GLfloat) pow((cs + 0.055) / 1.055, 2.4);
-         }
-      }
-      tableReady = GL_TRUE;
-   }
-   return table[cs8];
-}
-
+#include "util/format_srgb.h"
 
 
 /* Texel fetch routines for all supported formats
diff --git a/src/mesa/swrast/s_texfetch_tmp.h b/src/mesa/swrast/s_texfetch_tmp.h
index deda592..72037ec 100644
--- a/src/mesa/swrast/s_texfetch_tmp.h
+++ b/src/mesa/swrast/s_texfetch_tmp.h
@@ -737,9 +737,9 @@ FETCH(BGR_SRGB8)(const struct swrast_texture_image *texImage,
                  GLint i, GLint j, GLint k, GLfloat *texel)
 {
    const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 3);
-   texel[RCOMP] = nonlinear_to_linear(src[2]);
-   texel[GCOMP] = nonlinear_to_linear(src[1]);
-   texel[BCOMP] = nonlinear_to_linear(src[0]);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(src[2]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(src[1]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(src[0]);
    texel[ACOMP] = 1.0F;
 }
 
@@ -749,9 +749,9 @@ FETCH(A8B8G8R8_SRGB)(const struct swrast_texture_image *texImage,
                      GLint i, GLint j, GLint k, GLfloat *texel)
 {
    const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
-   texel[RCOMP] = nonlinear_to_linear( (s >> 24) );
-   texel[GCOMP] = nonlinear_to_linear( (s >> 16) & 0xff );
-   texel[BCOMP] = nonlinear_to_linear( (s >>  8) & 0xff );
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 24) );
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff );
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s >>  8) & 0xff );
    texel[ACOMP] = UBYTE_TO_FLOAT( (s      ) & 0xff ); /* linear! */
 }
 
@@ -761,9 +761,9 @@ FETCH(B8G8R8A8_SRGB)(const struct swrast_texture_image *texImage,
                      GLint i, GLint j, GLint k, GLfloat *texel)
 {
    const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
-   texel[RCOMP] = nonlinear_to_linear( (s >> 16) & 0xff );
-   texel[GCOMP] = nonlinear_to_linear( (s >>  8) & 0xff );
-   texel[BCOMP] = nonlinear_to_linear( (s      ) & 0xff );
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff );
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >>  8) & 0xff );
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s      ) & 0xff );
    texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); /* linear! */
 }
 
@@ -773,9 +773,9 @@ FETCH(R8G8B8A8_SRGB)(const struct swrast_texture_image *texImage,
                      GLint i, GLint j, GLint k, GLfloat *texel)
 {
    const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
-   texel[RCOMP] = nonlinear_to_linear( (s      ) & 0xff );
-   texel[GCOMP] = nonlinear_to_linear( (s >>  8) & 0xff );
-   texel[BCOMP] = nonlinear_to_linear( (s >> 16) & 0xff );
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s      ) & 0xff );
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >>  8) & 0xff );
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff );
    texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); /* linear! */
 }
 
@@ -785,9 +785,9 @@ FETCH(R8G8B8X8_SRGB)(const struct swrast_texture_image *texImage,
                      GLint i, GLint j, GLint k, GLfloat *texel)
 {
    const GLuint s = *TEXEL_ADDR(GLuint, texImage, i, j, k, 1);
-   texel[RCOMP] = nonlinear_to_linear( (s      ) & 0xff );
-   texel[GCOMP] = nonlinear_to_linear( (s >>  8) & 0xff );
-   texel[BCOMP] = nonlinear_to_linear( (s >> 16) & 0xff );
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float( (s      ) & 0xff );
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float( (s >>  8) & 0xff );
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float( (s >> 16) & 0xff );
    texel[ACOMP] = 1.0f;
 }
 
@@ -799,7 +799,7 @@ FETCH(L_SRGB8)(const struct swrast_texture_image *texImage,
    const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 1);
    texel[RCOMP] =
    texel[GCOMP] =
-   texel[BCOMP] = nonlinear_to_linear(src[0]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(src[0]);
    texel[ACOMP] = 1.0F;
 }
 
@@ -811,7 +811,7 @@ FETCH(L8A8_SRGB)(const struct swrast_texture_image *texImage,
    const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 2);
    texel[RCOMP] =
    texel[GCOMP] =
-   texel[BCOMP] = nonlinear_to_linear(src[0]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(src[0]);
    texel[ACOMP] = UBYTE_TO_FLOAT(src[1]); /* linear */
 }
 
diff --git a/src/util/format_srgb.h b/src/util/format_srgb.h
index 8e92c38..17ba283 100644
--- a/src/util/format_srgb.h
+++ b/src/util/format_srgb.h
@@ -38,6 +38,7 @@
 #define U_FORMAT_SRGB_H_
 
 #include <stdint.h>
+#include <math.h>
 
 extern const float
 util_format_srgb_8unorm_to_linear_float_table[256];
@@ -52,6 +53,20 @@ extern const unsigned
 util_format_linear_to_srgb_helper_table[104];
 
 
+static inline float
+util_format_linear_to_srgb_float(float cl)
+{
+   if (cl < 0.0f)
+      return 0.0f;
+   else if (cl < 0.0031308f)
+      return 12.92f * cl;
+   else if (cl < 1.0f)
+      return 1.055f * powf(cl, 0.41666f) - 0.055f;
+   else
+      return 1.0f;
+}
+
+
 /**
  * Convert a unclamped linear float to srgb value in the [0,255].
  */
-- 
2.0.1



More information about the mesa-dev mailing list