[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