gallivm: Centralize SoA swizzling into a single place.
authorJosé Fonseca <jfonseca@vmware.com>
Sat, 8 May 2010 11:52:50 +0000 (12:52 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 8 May 2010 11:52:50 +0000 (12:52 +0100)
src/gallium/auxiliary/gallivm/lp_bld_format.h
src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
src/gallium/auxiliary/gallivm/lp_bld_swizzle.h

index 085937588ff260b4a314f36ea3b01e33948afe13..d873c7a45763820ffeab6bc4ed95a0999a3f724a 100644 (file)
@@ -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);
 
index 26b947b3b1c3a182806bc4fb4112236f146aa2f7..c5de5ce72d9c3c564f52770bebc816e7975a2475 100644 (file)
@@ -26,6 +26,8 @@
  **************************************************************************/
 
 
+#include "pipe/p_defines.h"
+
 #include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_string.h"
 #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);
 }
 
 
index 3f0ea05b79519c522dd759459c362e8872281bf7..dd0053f212dad089baf77f9c43b0c715c8b2942b 100644 (file)
@@ -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);
 }
 
 
index 278c838eaca5fb63a4c531ebe1a379b5cfae68bb..e101d2866b42f049d1aae37a6459f3cc52f2fd58 100644 (file)
@@ -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);
+}
index 138ca620e63468b5079e982d9846a0c1a924655a..4f4fa777c930fa433213acf01f1109f94b5ff7a4 100644 (file)
@@ -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 */