summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2010-11-04 10:01:28 -0600
committerBrian Paul <[email protected]>2010-11-04 10:01:28 -0600
commite7f5d19a1106351f2db8f62f59f51be86eaa93df (patch)
treeded2036bf8c4f9b46b8deae293f64267bdc1d4a0 /src/gallium/auxiliary
parentfb94747b6639ba976aaaaba5a37aa2fe56999310 (diff)
gallivm: implement execution mask for scatter stores
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index e15baa3727c..a74cefd41e1 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -120,9 +120,12 @@ struct lp_build_tgsi_soa_context
{
struct lp_build_context base;
- /* Builder for integer masks and indices */
+ /* Builder for vector integer masks and indices */
struct lp_build_context uint_bld;
+ /* Builder for scalar elements of shader's data type (float) */
+ struct lp_build_context elem_bld;
+
LLVMValueRef consts_ptr;
const LLVMValueRef *pos;
const LLVMValueRef (*inputs)[NUM_CHANNELS];
@@ -472,14 +475,26 @@ build_gather(struct lp_build_tgsi_soa_context *bld,
* Scatter/store vector.
*/
static void
-build_scatter(struct lp_build_tgsi_soa_context *bld,
- LLVMValueRef base_ptr,
- LLVMValueRef indexes,
- LLVMValueRef values)
+emit_mask_scatter(struct lp_build_tgsi_soa_context *bld,
+ LLVMValueRef base_ptr,
+ LLVMValueRef indexes,
+ LLVMValueRef values,
+ struct lp_exec_mask *mask,
+ LLVMValueRef pred)
{
LLVMBuilderRef builder = bld->base.builder;
unsigned i;
+ /* Mix the predicate and execution mask */
+ if (mask->has_mask) {
+ if (pred) {
+ pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
+ }
+ else {
+ pred = mask->exec_mask;
+ }
+ }
+
/*
* Loop over elements of index_vec, store scalar value.
*/
@@ -488,12 +503,22 @@ build_scatter(struct lp_build_tgsi_soa_context *bld,
LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, "");
LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr");
LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val");
+ LLVMValueRef scalar_pred = pred ?
+ LLVMBuildExtractElement(builder, pred, ii, "scatter_pred") : NULL;
if (0)
lp_build_printf(builder, "scatter %d: val %f at %d %p\n",
ii, val, index, scalar_ptr);
- LLVMBuildStore(builder, val, scalar_ptr);
+ if (scalar_pred) {
+ LLVMValueRef real_val, dst_val;
+ dst_val = LLVMBuildLoad(builder, scalar_ptr, "");
+ real_val = lp_build_select(&bld->elem_bld, scalar_pred, val, dst_val);
+ LLVMBuildStore(builder, real_val, scalar_ptr);
+ }
+ else {
+ LLVMBuildStore(builder, val, scalar_ptr);
+ }
}
}
@@ -847,7 +872,8 @@ emit_store(
float_ptr_type, "");
/* Scatter store values into temp registers */
- build_scatter(bld, temps_array, index_vec, value);
+ emit_mask_scatter(bld, temps_array, index_vec, value,
+ &bld->exec_mask, pred);
}
else {
LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
@@ -2192,6 +2218,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
memset(&bld, 0, sizeof bld);
lp_build_context_init(&bld.base, builder, type);
lp_build_context_init(&bld.uint_bld, builder, lp_uint_type(type));
+ lp_build_context_init(&bld.elem_bld, builder, lp_elem_type(type));
bld.mask = mask;
bld.pos = pos;
bld.inputs = inputs;