From: José Fonseca Date: Sat, 8 May 2010 11:52:50 +0000 (+0100) Subject: gallivm: Centralize SoA swizzling into a single place. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2c2debaea71eb99322c2371f1c581e9748cda91f;p=mesa.git gallivm: Centralize SoA swizzling into a single place. --- diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h index 085937588ff..d873c7a4576 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h @@ -40,6 +40,7 @@ struct util_format_description; struct lp_type; +struct lp_build_context; /* @@ -70,7 +71,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder, void lp_build_format_swizzle_soa(const struct util_format_description *format_desc, - struct lp_type type, + struct lp_build_context *bld, const LLVMValueRef *unswizzled, LLVMValueRef *swizzled); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index 26b947b3b1c..c5de5ce72d9 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c @@ -26,6 +26,8 @@ **************************************************************************/ +#include "pipe/p_defines.h" + #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -33,51 +35,38 @@ #include "lp_bld_type.h" #include "lp_bld_const.h" #include "lp_bld_conv.h" +#include "lp_bld_swizzle.h" #include "lp_bld_sample.h" /* for lp_build_gather */ #include "lp_bld_format.h" -static LLVMValueRef -lp_build_format_swizzle_chan_soa(struct lp_type type, - const LLVMValueRef *unswizzled, - enum util_format_swizzle swizzle) -{ - switch (swizzle) { - case UTIL_FORMAT_SWIZZLE_X: - case UTIL_FORMAT_SWIZZLE_Y: - case UTIL_FORMAT_SWIZZLE_Z: - case UTIL_FORMAT_SWIZZLE_W: - return unswizzled[swizzle]; - case UTIL_FORMAT_SWIZZLE_0: - return lp_build_zero(type); - case UTIL_FORMAT_SWIZZLE_1: - return lp_build_one(type); - case UTIL_FORMAT_SWIZZLE_NONE: - return lp_build_undef(type); - default: - assert(0); - return lp_build_undef(type); - } -} - - void lp_build_format_swizzle_soa(const struct util_format_description *format_desc, - struct lp_type type, + struct lp_build_context *bld, const LLVMValueRef *unswizzled, LLVMValueRef *swizzled) { - if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { + assert(UTIL_FORMAT_SWIZZLE_0 == PIPE_SWIZZLE_ZERO); + assert(UTIL_FORMAT_SWIZZLE_1 == PIPE_SWIZZLE_ONE); + + if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { + /* + * Return zzz1 for depth-stencil formats. + * + * XXX: Allow to control the depth swizzle with an additional parameter, + * as the caller may wish another depth swizzle, or retain the stencil + * value. + */ enum util_format_swizzle swizzle = format_desc->swizzle[0]; - LLVMValueRef depth = lp_build_format_swizzle_chan_soa(type, unswizzled, swizzle); + LLVMValueRef depth = lp_build_swizzle_soa_channel(bld, unswizzled, swizzle); swizzled[2] = swizzled[1] = swizzled[0] = depth; - swizzled[3] = lp_build_one(type); + swizzled[3] = bld->one; } else { unsigned chan; for (chan = 0; chan < 4; ++chan) { enum util_format_swizzle swizzle = format_desc->swizzle[chan]; - swizzled[chan] = lp_build_format_swizzle_chan_soa(type, unswizzled, swizzle); + swizzled[chan] = lp_build_swizzle_soa_channel(bld, unswizzled, swizzle); } } } @@ -108,6 +97,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, LLVMValueRef packed, LLVMValueRef *rgba) { + struct lp_build_context bld; LLVMValueRef inputs[4]; unsigned start; unsigned chan; @@ -120,6 +110,8 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, assert(type.floating); assert(type.width == 32); + lp_build_context_init(&bld, builder, type); + /* Decode the input vector components */ start = 0; for (chan = 0; chan < format_desc->nr_channels; ++chan) { @@ -250,7 +242,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, start = stop; } - lp_build_format_swizzle_soa(format_desc, type, inputs, rgba); + lp_build_format_swizzle_soa(format_desc, &bld, inputs, rgba); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 3f0ea05b795..dd0053f212d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -186,50 +186,18 @@ texture_dims(enum pipe_texture_target tex) } -static LLVMValueRef -lp_build_swizzle_chan_soa(struct lp_type type, - const LLVMValueRef *unswizzled, - enum util_format_swizzle swizzle) -{ - switch (swizzle) { - case PIPE_SWIZZLE_RED: - case PIPE_SWIZZLE_GREEN: - case PIPE_SWIZZLE_BLUE: - case PIPE_SWIZZLE_ALPHA: - return unswizzled[swizzle]; - case PIPE_SWIZZLE_ZERO: - return lp_build_zero(type); - case PIPE_SWIZZLE_ONE: - return lp_build_one(type); - default: - assert(0); - return lp_build_undef(type); - } -} - - static void -lp_build_swizzle_soa(struct lp_build_sample_context *bld, - LLVMValueRef *texel) +apply_sampler_swizzle(struct lp_build_sample_context *bld, + LLVMValueRef *texel) { - LLVMValueRef unswizzled[4]; unsigned char swizzles[4]; - unsigned chan; - - for (chan = 0; chan < 4; ++chan) { - unswizzled[chan] = texel[chan]; - } swizzles[0] = bld->static_state->swizzle_r; swizzles[1] = bld->static_state->swizzle_g; swizzles[2] = bld->static_state->swizzle_b; swizzles[3] = bld->static_state->swizzle_a; - for (chan = 0; chan < 4; ++chan) { - unsigned swizzle = swizzles[chan]; - texel[chan] = lp_build_swizzle_chan_soa(bld->texel_type, - unswizzled, swizzle); - } + lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles); } @@ -345,7 +313,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld, i, j, texel); - lp_build_swizzle_soa(bld, texel); + apply_sampler_swizzle(bld, texel); /* * Note: if we find an app which frequently samples the texture border @@ -2023,10 +1991,10 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld, packed, unswizzled); lp_build_format_swizzle_soa(bld->format_desc, - bld->texel_type, unswizzled, - texel); + &bld->texel_bld, + unswizzled, texel); - lp_build_swizzle_soa(bld, texel); + apply_sampler_swizzle(bld, texel); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c index 278c838eaca..e101d2866b4 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c @@ -60,6 +60,9 @@ lp_build_broadcast(LLVMBuilderRef builder, } +/** + * Broadcast + */ LLVMValueRef lp_build_broadcast_scalar(struct lp_build_context *bld, LLVMValueRef scalar) @@ -237,3 +240,78 @@ lp_build_swizzle2_aos(struct lp_build_context *bld, } +/** + * Extended swizzle of a single channel of a SoA vector. + * + * @param bld building context + * @param unswizzled array with the 4 unswizzled values + * @param swizzle one of the PIPE_SWIZZLE_* + * + * @return the swizzled value. + */ +LLVMValueRef +lp_build_swizzle_soa_channel(struct lp_build_context *bld, + const LLVMValueRef *unswizzled, + unsigned swizzle) +{ + switch (swizzle) { + case PIPE_SWIZZLE_RED: + case PIPE_SWIZZLE_GREEN: + case PIPE_SWIZZLE_BLUE: + case PIPE_SWIZZLE_ALPHA: + return unswizzled[swizzle]; + case PIPE_SWIZZLE_ZERO: + return bld->zero; + case PIPE_SWIZZLE_ONE: + return bld->one; + default: + assert(0); + return bld->undef; + } +} + + +/** + * Extended swizzle of a SoA vector. + * + * @param bld building context + * @param unswizzled array with the 4 unswizzled values + * @param swizzles array of PIPE_SWIZZLE_* + * @param swizzled output swizzled values + */ +void +lp_build_swizzle_soa(struct lp_build_context *bld, + const LLVMValueRef *unswizzled, + const unsigned char swizzles[4], + LLVMValueRef *swizzled) +{ + unsigned chan; + + for (chan = 0; chan < 4; ++chan) { + swizzled[chan] = lp_build_swizzle_soa_channel(bld, unswizzled, + swizzles[chan]); + } +} + + +/** + * Do an extended swizzle of a SoA vector inplace. + * + * @param bld building context + * @param values intput/output array with the 4 values + * @param swizzles array of PIPE_SWIZZLE_* + */ +void +lp_build_swizzle_soa_inplace(struct lp_build_context *bld, + LLVMValueRef *values, + const unsigned char swizzles[4]) +{ + LLVMValueRef unswizzled[4]; + unsigned chan; + + for (chan = 0; chan < 4; ++chan) { + unswizzled[chan] = values[chan]; + } + + lp_build_swizzle_soa(bld, unswizzled, swizzles, values); +} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h index 138ca620e63..4f4fa777c93 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h @@ -88,4 +88,23 @@ lp_build_swizzle2_aos(struct lp_build_context *bld, const unsigned char swizzle[4]); +LLVMValueRef +lp_build_swizzle_soa_channel(struct lp_build_context *bld, + const LLVMValueRef *unswizzled, + unsigned swizzle); + + +void +lp_build_swizzle_soa(struct lp_build_context *bld, + const LLVMValueRef *unswizzled, + const unsigned char swizzles[4], + LLVMValueRef *swizzled); + + +void +lp_build_swizzle_soa_inplace(struct lp_build_context *bld, + LLVMValueRef *values, + const unsigned char swizzles[4]); + + #endif /* !LP_BLD_SWIZZLE_H */