From ae5f6ddc0529fcf29e26bc0c35ffa1e6ea2eb7b0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 27 Mar 2020 16:33:28 +1000 Subject: [PATCH] gallivm/nir: add an interpolation interface. This supports interpolating at a certain location, offsets, sample or centroid. Reviewed-by: Roland Scheidegger Part-of: --- src/gallium/auxiliary/gallivm/lp_bld_nir.c | 33 +++++++++++++++++++ src/gallium/auxiliary/gallivm/lp_bld_nir.h | 9 +++++ .../auxiliary/gallivm/lp_bld_nir_soa.c | 22 +++++++++++++ src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 10 ++++++ 4 files changed, 74 insertions(+) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.c b/src/gallium/auxiliary/gallivm/lp_bld_nir.c index 26303c946b4..32ad96e1a4a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.c @@ -1315,6 +1315,34 @@ static void visit_global_atomic(struct lp_build_nir_context *bld_base, bld_base->atomic_global(bld_base, instr->intrinsic, addr_bitsize, addr, val, val2, &result[0]); } +static void visit_interp(struct lp_build_nir_context *bld_base, + nir_intrinsic_instr *instr, + LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]) +{ + struct gallivm_state *gallivm = bld_base->base.gallivm; + LLVMBuilderRef builder = gallivm->builder; + nir_deref_instr *deref = nir_instr_as_deref(instr->src[0].ssa->parent_instr); + unsigned num_components = nir_dest_num_components(instr->dest); + nir_variable *var = nir_deref_instr_get_variable(deref); + unsigned const_index; + LLVMValueRef indir_index; + LLVMValueRef offsets[2] = { NULL, NULL }; + get_deref_offset(bld_base, deref, false, NULL, NULL, + &const_index, &indir_index); + bool centroid = instr->intrinsic == nir_intrinsic_interp_deref_at_centroid; + bool sample = false; + if (instr->intrinsic == nir_intrinsic_interp_deref_at_offset) { + for (unsigned i = 0; i < 2; i++) { + offsets[i] = LLVMBuildExtractValue(builder, get_src(bld_base, instr->src[1]), i, ""); + offsets[i] = cast_type(bld_base, offsets[i], nir_type_float, 32); + } + } else if (instr->intrinsic == nir_intrinsic_interp_deref_at_sample) { + offsets[0] = get_src(bld_base, instr->src[1]); + sample = true; + } + bld_base->interp_at(bld_base, num_components, var, centroid, sample, const_index, indir_index, offsets, result); +} + static void visit_intrinsic(struct lp_build_nir_context *bld_base, nir_intrinsic_instr *instr) { @@ -1460,6 +1488,11 @@ static void visit_intrinsic(struct lp_build_nir_context *bld_base, case nir_intrinsic_vote_ieq: bld_base->vote(bld_base, cast_type(bld_base, get_src(bld_base, instr->src[0]), nir_type_int, 32), instr, result); break; + case nir_intrinsic_interp_deref_at_offset: + case nir_intrinsic_interp_deref_at_centroid: + case nir_intrinsic_interp_deref_at_sample: + visit_interp(bld_base, instr, result); + break; default: assert(0); break; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.h b/src/gallium/auxiliary/gallivm/lp_bld_nir.h index c84ee99546f..c124cd59ba8 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.h @@ -175,6 +175,14 @@ struct lp_build_nir_context void (*vote)(struct lp_build_nir_context *bld_base, LLVMValueRef src, nir_intrinsic_instr *instr, LLVMValueRef dst[4]); void (*helper_invocation)(struct lp_build_nir_context *bld_base, LLVMValueRef *dst); + + void (*interp_at)(struct lp_build_nir_context *bld_base, + unsigned num_components, + nir_variable *var, + bool centroid, bool sample, + unsigned const_index, + LLVMValueRef indir_index, + LLVMValueRef offsets[2], LLVMValueRef dst[4]); // LLVMValueRef main_function }; @@ -210,6 +218,7 @@ struct lp_build_nir_soa_context const struct lp_build_gs_iface *gs_iface; const struct lp_build_tcs_iface *tcs_iface; const struct lp_build_tes_iface *tes_iface; + const struct lp_build_fs_iface *fs_iface; LLVMValueRef emitted_prims_vec_ptr[PIPE_MAX_VERTEX_STREAMS]; LLVMValueRef total_emitted_vertices_vec_ptr[PIPE_MAX_VERTEX_STREAMS]; LLVMValueRef emitted_vertices_vec_ptr[PIPE_MAX_VERTEX_STREAMS]; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index 0196b34bc91..d3f34be8603 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -1653,6 +1653,26 @@ static void emit_vote(struct lp_build_nir_context *bld_base, LLVMValueRef src, n result[0] = lp_build_broadcast_scalar(&bld_base->uint_bld, LLVMBuildLoad(builder, res_store, "")); } +static void +emit_interp_at(struct lp_build_nir_context *bld_base, + unsigned num_components, + nir_variable *var, + bool centroid, + bool sample, + unsigned const_index, + LLVMValueRef indir_index, + LLVMValueRef offsets[2], + LLVMValueRef dst[4]) +{ + struct lp_build_nir_soa_context *bld = (struct lp_build_nir_soa_context *)bld_base; + + for (unsigned i = 0; i < num_components; i++) { + dst[i] = bld->fs_iface->interp_fn(bld->fs_iface, &bld_base->base, + const_index + var->data.driver_location, i + var->data.location_frac, + centroid, sample, indir_index, offsets); + } +} + void lp_build_nir_soa(struct gallivm_state *gallivm, struct nir_shader *shader, const struct lp_build_tgsi_params *params, @@ -1749,6 +1769,7 @@ void lp_build_nir_soa(struct gallivm_state *gallivm, bld.bld_base.image_size = emit_image_size; bld.bld_base.vote = emit_vote; bld.bld_base.helper_invocation = emit_helper_invocation; + bld.bld_base.interp_at = emit_interp_at; bld.mask = params->mask; bld.inputs = params->inputs; @@ -1773,6 +1794,7 @@ void lp_build_nir_soa(struct gallivm_state *gallivm, bld.gs_iface = params->gs_iface; bld.tcs_iface = params->tcs_iface; bld.tes_iface = params->tes_iface; + bld.fs_iface = params->fs_iface; if (bld.gs_iface) { struct lp_build_context *uint_bld = &bld.bld_base.uint_bld; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index a543e2e69cc..b1b619e34d2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -243,6 +243,15 @@ struct lp_build_image_soa const struct lp_sampler_size_query_params *params); }; +struct lp_build_fs_iface; +struct lp_build_fs_iface { + LLVMValueRef (*interp_fn)(const struct lp_build_fs_iface *iface, + struct lp_build_context *bld, + unsigned attrib, unsigned chan, + bool centroid, bool sample, + LLVMValueRef indir_index, LLVMValueRef offsets[2]); +}; + void lp_build_tgsi_info(const struct tgsi_token *tokens, struct lp_tgsi_info *info); @@ -268,6 +277,7 @@ struct lp_build_tgsi_params { LLVMValueRef shared_ptr; const struct lp_build_coro_suspend_info *coro; LLVMValueRef kernel_args; + const struct lp_build_fs_iface *fs_iface; }; void -- 2.30.2