gallivm: Centralize SoA swizzling into a single place.

This commit is contained in:
José Fonseca 2010-05-08 12:52:50 +01:00
parent ff6c78f44f
commit 2c2debaea7
5 changed files with 128 additions and 70 deletions

View 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);

View 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"
@ -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);
}

View 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);
}

View 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);
}

View 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 */