From 8154bdf25ba2f78dc905759e50adf840471e334a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 19 Mar 2020 15:24:11 +1000 Subject: [PATCH] llvmpipe: add centroid interpolation support. This just adds the implementation and API to the interpolation builders. Reviewed-by: Roland Scheidegger Part-of: --- src/gallium/drivers/llvmpipe/lp_bld_interp.c | 60 ++++++++++++++++++-- src/gallium/drivers/llvmpipe/lp_bld_interp.h | 9 ++- src/gallium/drivers/llvmpipe/lp_state_fs.c | 3 +- 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c index 9f6b577a9ee..6ca163f5a18 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c @@ -43,6 +43,8 @@ #include "gallivm/lp_bld_arit.h" #include "gallivm/lp_bld_swizzle.h" #include "gallivm/lp_bld_flow.h" +#include "gallivm/lp_bld_logic.h" +#include "gallivm/lp_bld_struct.h" #include "lp_bld_interp.h" @@ -238,6 +240,7 @@ static void attribs_update_simple(struct lp_build_interp_soa_context *bld, struct gallivm_state *gallivm, LLVMValueRef loop_iter, + LLVMValueRef mask_store, int start, int end) { @@ -266,6 +269,7 @@ attribs_update_simple(struct lp_build_interp_soa_context *bld, for (attrib = start; attrib < end; attrib++) { const unsigned mask = bld->mask[attrib]; const unsigned interp = bld->interp[attrib]; + const unsigned loc = bld->interp_loc[attrib]; unsigned chan; for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { @@ -274,6 +278,7 @@ attribs_update_simple(struct lp_build_interp_soa_context *bld, LLVMValueRef dadx = coeff_bld->zero; LLVMValueRef dady = coeff_bld->zero; LLVMValueRef a = coeff_bld->zero; + LLVMValueRef chan_pixoffx = pixoffx, chan_pixoffy = pixoffy; index = lp_build_const_int32(gallivm, chan); switch (interp) { @@ -303,12 +308,50 @@ attribs_update_simple(struct lp_build_interp_soa_context *bld, a = lp_build_extract_broadcast(gallivm, setup_bld->type, coeff_bld->type, bld->a0aos[attrib], index); + + if (bld->coverage_samples > 1) { + LLVMValueRef xoffset = lp_build_const_vec(gallivm, coeff_bld->type, bld->pos_offset); + LLVMValueRef yoffset = lp_build_const_vec(gallivm, coeff_bld->type, bld->pos_offset); + if (loc == TGSI_INTERPOLATE_LOC_CENTROID) { + LLVMValueRef centroid_x_offset = lp_build_const_vec(gallivm, coeff_bld->type, bld->pos_offset); + LLVMValueRef centroid_y_offset = lp_build_const_vec(gallivm, coeff_bld->type, bld->pos_offset); + + /* for centroid find covered samples for this quad. */ + /* if all samples are covered use pixel centers */ + LLVMValueRef s_mask_and = NULL; + for (int s = bld->coverage_samples - 1; s >= 0; s--) { + LLVMValueRef sample_cov; + LLVMValueRef s_mask_idx = LLVMBuildMul(builder, bld->num_loop, lp_build_const_int32(gallivm, s), ""); + + s_mask_idx = LLVMBuildAdd(builder, s_mask_idx, loop_iter, ""); + sample_cov = lp_build_pointer_get(builder, mask_store, s_mask_idx); + if (s == bld->coverage_samples - 1) + s_mask_and = sample_cov; + else + s_mask_and = LLVMBuildAnd(builder, s_mask_and, sample_cov, ""); + + LLVMValueRef x_val_idx = lp_build_const_int32(gallivm, s * 2); + LLVMValueRef y_val_idx = lp_build_const_int32(gallivm, s * 2 + 1); + + x_val_idx = LLVMBuildGEP(builder, bld->sample_pos_array, &x_val_idx, 1, ""); + y_val_idx = LLVMBuildGEP(builder, bld->sample_pos_array, &y_val_idx, 1, ""); + x_val_idx = lp_build_broadcast_scalar(coeff_bld, LLVMBuildLoad(builder, x_val_idx, "")); + y_val_idx = lp_build_broadcast_scalar(coeff_bld, LLVMBuildLoad(builder, y_val_idx, "")); + centroid_x_offset = lp_build_select(coeff_bld, sample_cov, x_val_idx, centroid_x_offset); + centroid_y_offset = lp_build_select(coeff_bld, sample_cov, y_val_idx, centroid_y_offset); + } + xoffset = lp_build_select(coeff_bld, s_mask_and, xoffset, centroid_x_offset); + yoffset = lp_build_select(coeff_bld, s_mask_and, yoffset, centroid_y_offset); + } + chan_pixoffx = lp_build_add(coeff_bld, chan_pixoffx, xoffset); + chan_pixoffy = lp_build_add(coeff_bld, chan_pixoffy, yoffset); + } } /* * a = a0 + (x * dadx + y * dady) */ - a = lp_build_fmuladd(builder, dadx, pixoffx, a); - a = lp_build_fmuladd(builder, dady, pixoffy, a); + a = lp_build_fmuladd(builder, dadx, chan_pixoffx, a); + a = lp_build_fmuladd(builder, dady, chan_pixoffy, a); if (interp == LP_INTERP_PERSPECTIVE) { if (oow == NULL) { @@ -693,6 +736,9 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, unsigned num_inputs, const struct lp_shader_input *inputs, boolean pixel_center_integer, + unsigned coverage_samples, + LLVMValueRef sample_pos_array, + LLVMValueRef num_loop, boolean depth_clamp, LLVMBuilderRef builder, struct lp_type type, @@ -758,6 +804,9 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, bld->pos_offset = 0.5; } bld->depth_clamp = depth_clamp; + bld->coverage_samples = coverage_samples; + bld->num_loop = num_loop; + bld->sample_pos_array = sample_pos_array; pos_init(bld, x0, y0); @@ -809,10 +858,11 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, void lp_build_interp_soa_update_inputs_dyn(struct lp_build_interp_soa_context *bld, struct gallivm_state *gallivm, - LLVMValueRef quad_start_index) + LLVMValueRef quad_start_index, + LLVMValueRef mask_store) { if (bld->simple_interp) { - attribs_update_simple(bld, gallivm, quad_start_index, 1, bld->num_attribs); + attribs_update_simple(bld, gallivm, quad_start_index, mask_store, 1, bld->num_attribs); } else { attribs_update(bld, gallivm, quad_start_index, 1, bld->num_attribs); @@ -825,7 +875,7 @@ lp_build_interp_soa_update_pos_dyn(struct lp_build_interp_soa_context *bld, LLVMValueRef quad_start_index) { if (bld->simple_interp) { - attribs_update_simple(bld, gallivm, quad_start_index, 0, 1); + attribs_update_simple(bld, gallivm, quad_start_index, NULL, 0, 1); } else { attribs_update(bld, gallivm, quad_start_index, 0, 1); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h index 867a95e41d8..d2efdef1f45 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h @@ -90,6 +90,9 @@ struct lp_build_interp_soa_context boolean depth_clamp; double pos_offset; + unsigned coverage_samples; + LLVMValueRef num_loop; + LLVMValueRef sample_pos_array; LLVMValueRef x; LLVMValueRef y; @@ -119,6 +122,9 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, unsigned num_inputs, const struct lp_shader_input *inputs, boolean pixel_center_integer, + unsigned coverage_samples, + LLVMValueRef sample_pos_array, + LLVMValueRef num_loop, boolean depth_clamp, LLVMBuilderRef builder, struct lp_type type, @@ -131,7 +137,8 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, void lp_build_interp_soa_update_inputs_dyn(struct lp_build_interp_soa_context *bld, struct gallivm_state *gallivm, - LLVMValueRef quad_start_index); + LLVMValueRef quad_start_index, + LLVMValueRef mask_store); void lp_build_interp_soa_update_pos_dyn(struct lp_build_interp_soa_context *bld, diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 93da53340e6..aace89507ae 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -492,7 +492,7 @@ generate_fs_loop(struct gallivm_state *gallivm, lp_build_mask_check(&mask); } - lp_build_interp_soa_update_inputs_dyn(interp, gallivm, loop_state.counter); + lp_build_interp_soa_update_inputs_dyn(interp, gallivm, loop_state.counter, NULL); struct lp_build_tgsi_params params; memset(¶ms, 0, sizeof(params)); @@ -2653,6 +2653,7 @@ generate_fragment(struct llvmpipe_context *lp, shader->info.base.num_inputs, inputs, pixel_center_integer, + 1, NULL, num_loop, key->depth_clamp, builder, fs_type, a0_ptr, dadx_ptr, dady_ptr, -- 2.30.2