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)
{
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;
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
};
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];
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,
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;
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;
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);
LLVMValueRef shared_ptr;
const struct lp_build_coro_suspend_info *coro;
LLVMValueRef kernel_args;
+ const struct lp_build_fs_iface *fs_iface;
};
void