Mesa (master): gallivm/nir: add an interpolation interface.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 19 00:45:21 UTC 2020


Module: Mesa
Branch: master
Commit: ae5f6ddc0529fcf29e26bc0c35ffa1e6ea2eb7b0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ae5f6ddc0529fcf29e26bc0c35ffa1e6ea2eb7b0

Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Mar 27 16:33:28 2020 +1000

gallivm/nir: add an interpolation interface.

This supports interpolating at a certain location, offsets,
sample or centroid.

Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5050>

---

 src/gallium/auxiliary/gallivm/lp_bld_nir.c     | 33 ++++++++++++++++++++++++++
 src/gallium/auxiliary/gallivm/lp_bld_nir.h     |  9 +++++++
 src/gallium/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



More information about the mesa-commit mailing list