struct util_format_description;
struct lp_type;
+struct lp_build_context;
/*
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);
**************************************************************************/
+#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);
}
}
}
LLVMValueRef packed,
LLVMValueRef *rgba)
{
+ struct lp_build_context bld;
LLVMValueRef inputs[4];
unsigned start;
unsigned chan;
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) {
start = stop;
}
- lp_build_format_swizzle_soa(format_desc, type, inputs, rgba);
+ lp_build_format_swizzle_soa(format_desc, &bld, inputs, rgba);
}
}
-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);
}
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
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);
}
}
+/**
+ * Broadcast
+ */
LLVMValueRef
lp_build_broadcast_scalar(struct lp_build_context *bld,
LLVMValueRef scalar)
}
+/**
+ * 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);
+}
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 */