[Mesa-dev] [PATCH 2/2] gallivm: handle srgb-to-linear and linear-to-srgb conversions

Jose Fonseca jfonseca at vmware.com
Thu Jul 11 06:50:26 PDT 2013



----- Original Message -----
> From: Roland Scheidegger <sroland at vmware.com>
> 
> srgb-to-linear is using 3rd degree polynomial for now which should be _just_
> good enough. Reverse is using some rational polynomials and is quite
> accurate,
> though not hooked into llvmpipe's blend code yet and hence unused (untested).
> Using a table might also be an option (for srgb-to-linear especially).
> This does not enable any new features yet because EXT_texture_srgb was
> already
> supported via util_format fallbacks, but performance was lacking probably due
> to the external function call (the table used by the util_format_srgb code
> may
> not be all that much slower on its own).
> Some performance figures (taken from modified gloss, replaced both base and
> sphere texture to use GL_SRGB instead of GL_RGB, measured on 1Ghz Sandy
> Bridge,
> the numbers aren't terribly accurate):
> 
> normal gloss, aos, 8-wide: 47 fps
> normal gloss, aos, 4-wide: 48 fps
> 
> normal gloss, forced to soa, 8-wide: 48 fps
> normal gloss, forced to soa, 4-wide: 47 fps
> 
> patched gloss, old code, soa, 8-wide: 21 fps
> patched gloss, old code, soa, 4-wide: 24 fps
> 
> patched gloss, new code, soa, 8-wide: 41 fps
> patched gloss, new code, soa, 4-wide: 38 fps

Indeed, not a big difference.  Though these figures seem low overall -- I get 72.5275 on my machine.  This was with release/profile build, right?

Eitherway the patch looks good.

Jose


> So there's a performance hit but it seems acceptable, certainly better
> than using the fallback.
> Note the new code only works for 4x8bit srgb formats, others (L8/L8A8) will
> continue to use the old util_format fallback, because I can't be bothered
> to write code for formats noone uses anyway (as decoding is done as part of
> lp_build_unpack_rgba_soa which can only handle block type width of 32).
> Compressed srgb formats should get their own path though eventually (it is
> going to be expensive in any case, first decompress, then convert).
> No piglit regressions.
> ---
>  src/gallium/auxiliary/Makefile.sources            |    1 +
>  src/gallium/auxiliary/gallivm/lp_bld_format.h     |   11 +++++++++
>  src/gallium/auxiliary/gallivm/lp_bld_format_soa.c |   25
>  ++++++++++++++++-----
>  3 files changed, 31 insertions(+), 6 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/Makefile.sources
> b/src/gallium/auxiliary/Makefile.sources
> index 4751762..8cffeb0 100644
> --- a/src/gallium/auxiliary/Makefile.sources
> +++ b/src/gallium/auxiliary/Makefile.sources
> @@ -172,6 +172,7 @@ GALLIVM_SOURCES := \
>          gallivm/lp_bld_format_aos.c \
>          gallivm/lp_bld_format_aos_array.c \
>  	gallivm/lp_bld_format_float.c \
> +        gallivm/lp_bld_format_srgb.c \
>          gallivm/lp_bld_format_soa.c \
>          gallivm/lp_bld_format_yuv.c \
>          gallivm/lp_bld_gather.c \
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h
> b/src/gallium/auxiliary/gallivm/lp_bld_format.h
> index 12a0318..744d002 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_format.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h
> @@ -158,4 +158,15 @@ lp_build_rgb9e5_to_float(struct gallivm_state *gallivm,
>                           LLVMValueRef src,
>                           LLVMValueRef *dst);
>  
> +LLVMValueRef
> +lp_build_linear_to_srgb(struct gallivm_state *gallivm,
> +                        struct lp_type src_type,
> +                        LLVMValueRef src);
> +
> +LLVMValueRef
> +lp_build_srgb_to_linear(struct gallivm_state *gallivm,
> +                        struct lp_type src_type,
> +                        LLVMValueRef src);
> +
> +
>  #endif /* !LP_BLD_FORMAT_H */
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
> b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
> index 4c6bd81..114ce03 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
> @@ -163,11 +163,23 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm,
>            */
>  
>           if (type.floating) {
> -            if(format_desc->channel[chan].normalized)
> -               input = lp_build_unsigned_norm_to_float(gallivm, width, type,
> input);
> -            else
> -               input = LLVMBuildSIToFP(builder, input,
> -                                       lp_build_vec_type(gallivm, type),
> "");
> +            if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
> +               assert(width == 8);
> +               if (format_desc->swizzle[3] == chan) {
> +                  input = lp_build_unsigned_norm_to_float(gallivm, width,
> type, input);
> +               }
> +               else {
> +                  struct lp_type conv_type = lp_uint_type(type);
> +                  input = lp_build_srgb_to_linear(gallivm, conv_type,
> input);
> +               }
> +            }
> +            else {
> +               if(format_desc->channel[chan].normalized)
> +                  input = lp_build_unsigned_norm_to_float(gallivm, width,
> type, input);
> +               else
> +                  input = LLVMBuildSIToFP(builder, input,
> +                                          lp_build_vec_type(gallivm, type),
> "");
> +            }
>           }
>           else if (format_desc->channel[chan].pure_integer) {
>              /* Nothing to do */
> @@ -344,6 +356,7 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm,
>  
>     if (format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
>         (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
> +        format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB ||
>          format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) &&
>         format_desc->block.width == 1 &&
>         format_desc->block.height == 1 &&
> @@ -394,7 +407,7 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm,
>        packed = lp_build_gather(gallivm, type.length,
>                                 format_desc->block.bits,
>                                 type.width, base_ptr, offset,
> -			       FALSE);
> +                               FALSE);
>        if (format_desc->format == PIPE_FORMAT_R11G11B10_FLOAT) {
>           lp_build_r11g11b10_to_float(gallivm, packed, rgba_out);
>        }
> --
> 1.7.9.5
> 


More information about the mesa-dev mailing list