ac: add ac_build_ddxy_interp() helper

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
Samuel Pitoiset 2019-04-10 17:16:50 +02:00
parent 4cb13e9462
commit 590a4c8981
4 changed files with 25 additions and 48 deletions

View File

@ -4037,3 +4037,23 @@ ac_build_frexp_mant(struct ac_llvm_context *ctx, LLVMValueRef src0,
return ac_build_intrinsic(ctx, intr, type, params, 1,
AC_FUNC_ATTR_READNONE);
}
/*
* this takes an I,J coordinate pair,
* and works out the X and Y derivatives.
* it returns DDX(I), DDX(J), DDY(I), DDY(J).
*/
LLVMValueRef
ac_build_ddxy_interp(struct ac_llvm_context *ctx, LLVMValueRef interp_ij)
{
LLVMValueRef result[4], a;
unsigned i;
for (i = 0; i < 2; i++) {
a = LLVMBuildExtractElement(ctx->builder, interp_ij,
LLVMConstInt(ctx->i32, i, false), "");
result[i] = ac_build_ddxy(ctx, AC_TID_MASK_TOP_LEFT, 1, a);
result[2+i] = ac_build_ddxy(ctx, AC_TID_MASK_TOP_LEFT, 2, a);
}
return ac_build_gather_values(ctx, result, 4);
}

View File

@ -686,6 +686,9 @@ LLVMValueRef
ac_build_frexp_mant(struct ac_llvm_context *ctx, LLVMValueRef src0,
unsigned bitsize);
LLVMValueRef
ac_build_ddxy_interp(struct ac_llvm_context *ctx, LLVMValueRef interp_ij);
#ifdef __cplusplus
}
#endif

View File

@ -540,27 +540,6 @@ static LLVMValueRef emit_ddxy(struct ac_nir_context *ctx,
return result;
}
/*
* this takes an I,J coordinate pair,
* and works out the X and Y derivatives.
* it returns DDX(I), DDX(J), DDY(I), DDY(J).
*/
static LLVMValueRef emit_ddxy_interp(
struct ac_nir_context *ctx,
LLVMValueRef interp_ij)
{
LLVMValueRef result[4], a;
unsigned i;
for (i = 0; i < 2; i++) {
a = LLVMBuildExtractElement(ctx->ac.builder, interp_ij,
LLVMConstInt(ctx->ac.i32, i, false), "");
result[i] = emit_ddxy(ctx, nir_op_fddx, a);
result[2+i] = emit_ddxy(ctx, nir_op_fddy, a);
}
return ac_build_gather_values(&ctx->ac, result, 4);
}
static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr)
{
LLVMValueRef src[4], result = NULL;
@ -3107,7 +3086,7 @@ static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
if (location == INTERP_CENTER) {
LLVMValueRef ij_out[2];
LLVMValueRef ddxy_out = emit_ddxy_interp(ctx, interp_param);
LLVMValueRef ddxy_out = ac_build_ddxy_interp(&ctx->ac, interp_param);
/*
* take the I then J parameters, and the DDX/Y for it, and

View File

@ -3924,31 +3924,6 @@ static void si_llvm_emit_ddxy(
emit_data->output[emit_data->chan] = val;
}
/*
* this takes an I,J coordinate pair,
* and works out the X and Y derivatives.
* it returns DDX(I), DDX(J), DDY(I), DDY(J).
*/
static LLVMValueRef si_llvm_emit_ddxy_interp(
struct lp_build_tgsi_context *bld_base,
LLVMValueRef interp_ij)
{
struct si_shader_context *ctx = si_shader_context(bld_base);
LLVMValueRef result[4], a;
unsigned i;
for (i = 0; i < 2; i++) {
a = LLVMBuildExtractElement(ctx->ac.builder, interp_ij,
LLVMConstInt(ctx->i32, i, 0), "");
result[i] = ac_build_ddxy(&ctx->ac, AC_TID_MASK_TOP_LEFT, 1,
ac_to_integer(&ctx->ac, a)); /* DDX */
result[2+i] = ac_build_ddxy(&ctx->ac, AC_TID_MASK_TOP_LEFT, 2,
ac_to_integer(&ctx->ac, a)); /* DDY */
}
return ac_build_gather_values(&ctx->ac, result, 4);
}
static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
struct lp_build_tgsi_context *bld_base,
struct lp_build_emit_data *emit_data)
@ -4062,7 +4037,7 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET ||
inst->Instruction.Opcode == TGSI_OPCODE_INTERP_SAMPLE) {
LLVMValueRef ij_out[2];
LLVMValueRef ddxy_out = si_llvm_emit_ddxy_interp(bld_base, interp_param);
LLVMValueRef ddxy_out = ac_build_ddxy_interp(&ctx->ac, interp_param);
/*
* take the I then J parameters, and the DDX/Y for it, and