summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2010-05-08 12:52:50 +0100
committerJosé Fonseca <jfonseca@vmware.com>2010-05-08 12:52:50 +0100
commit2c2debaea71eb99322c2371f1c581e9748cda91f (patch)
tree32e5ca425a9cba2103a6415ac297cc28dadf7795
parentff6c78f44f2f741f4825b07dbc15b3a951fe9b2c (diff)
gallivm: Centralize SoA swizzling into a single place.
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_format.h3
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_format_soa.c52
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c46
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_swizzle.c78
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_swizzle.h19
5 files changed, 128 insertions, 70 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h
index 085937588f..d873c7a457 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 26b947b3b1..c5de5ce72d 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 3f0ea05b79..dd0053f212 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 278c838eac..e101d2866b 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 138ca620e6..4f4fa777c9 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 */