gallivm: Centralize SoA swizzling into a single place.
This commit is contained in:
parent
ff6c78f44f
commit
2c2debaea7
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue