summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2018-04-25 18:57:46 +0200
committerJason Ekstrand <[email protected]>2018-06-22 20:54:00 -0700
commit657cedb12f5e8102c03fe67b60d3b7abf8f9936a (patch)
tree74f799ffc8e2d8b1e72f746e722e5a1b91b6d42c /src
parentd00e7d42f5a6bad04c60e399c7ca0b062d3b5dea (diff)
ac/nir: Add deref interp support.
Acked-by: Rob Clark <[email protected]> Acked-by: Bas Nieuwenhuizen <[email protected]> Acked-by: Dave Airlie <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/amd/common/ac_nir_to_llvm.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 8aee933b2d8..92ba7bd5b0c 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -2897,24 +2897,42 @@ static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
LLVMValueRef src_c0 = NULL;
LLVMValueRef src_c1 = NULL;
LLVMValueRef src0 = NULL;
- int input_index = instr->variables[0]->var->data.location - VARYING_SLOT_VAR0;
+ bool uses_deref_chain;
switch (instr->intrinsic) {
case nir_intrinsic_interp_var_at_centroid:
+ case nir_intrinsic_interp_var_at_sample:
+ case nir_intrinsic_interp_var_at_offset:
+ uses_deref_chain = true;
+ break;
+ default:
+ uses_deref_chain = false;
+ break;
+ }
+
+ nir_variable *var = uses_deref_chain ? instr->variables[0]->var : nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr));
+ int input_index = var->data.location - VARYING_SLOT_VAR0;
+ switch (instr->intrinsic) {
+ case nir_intrinsic_interp_var_at_centroid:
+ case nir_intrinsic_interp_deref_at_centroid:
location = INTERP_CENTROID;
break;
case nir_intrinsic_interp_var_at_sample:
case nir_intrinsic_interp_var_at_offset:
+ case nir_intrinsic_interp_deref_at_sample:
+ case nir_intrinsic_interp_deref_at_offset:
location = INTERP_CENTER;
- src0 = get_src(ctx, instr->src[0]);
+ src0 = get_src(ctx, instr->src[uses_deref_chain ? 0 : 1]);
break;
default:
break;
}
- if (instr->intrinsic == nir_intrinsic_interp_var_at_offset) {
+ if (instr->intrinsic == nir_intrinsic_interp_var_at_offset ||
+ instr->intrinsic == nir_intrinsic_interp_deref_at_offset) {
src_c0 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, src0, ctx->ac.i32_0, ""));
src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, src0, ctx->ac.i32_1, ""));
- } else if (instr->intrinsic == nir_intrinsic_interp_var_at_sample) {
+ } else if (instr->intrinsic == nir_intrinsic_interp_var_at_sample ||
+ instr->intrinsic == nir_intrinsic_interp_deref_at_sample) {
LLVMValueRef sample_position;
LLVMValueRef halfval = LLVMConstReal(ctx->ac.f32, 0.5f);
@@ -2926,7 +2944,7 @@ static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
src_c1 = LLVMBuildExtractElement(ctx->ac.builder, sample_position, ctx->ac.i32_1, "");
src_c1 = LLVMBuildFSub(ctx->ac.builder, src_c1, halfval, "");
}
- interp_param = ctx->abi->lookup_interp_param(ctx->abi, instr->variables[0]->var->data.interpolation, location);
+ interp_param = ctx->abi->lookup_interp_param(ctx->abi, var->data.interpolation, location);
attr_number = LLVMConstInt(ctx->ac.i32, input_index, false);
if (location == INTERP_CENTER) {
@@ -2990,7 +3008,7 @@ static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
}
}
return ac_build_varying_gather_values(&ctx->ac, result, instr->num_components,
- instr->variables[0]->var->data.location_frac);
+ var->data.location_frac);
}
static void visit_intrinsic(struct ac_nir_context *ctx,
@@ -3260,6 +3278,9 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
case nir_intrinsic_interp_var_at_centroid:
case nir_intrinsic_interp_var_at_sample:
case nir_intrinsic_interp_var_at_offset:
+ case nir_intrinsic_interp_deref_at_centroid:
+ case nir_intrinsic_interp_deref_at_sample:
+ case nir_intrinsic_interp_deref_at_offset:
result = visit_interp(ctx, instr);
break;
case nir_intrinsic_emit_vertex: