diff options
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 41 |
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; |