{
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];
* 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.
*/
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);
+ }
}
}
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,
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;