diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c b/src/gallium/drivers/etnaviv/etnaviv_compiler.c index a8ccf8747ac..8208d32c3e7 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c @@ -78,6 +78,7 @@ etna_compiler_create(const char *renderer, const struct etna_core_info *info) .lower_ufind_msb = true, .has_uclz = true, .no_integers = info->halti < 2, + .has_ddx_intrinsics = true, }; compiler->regs = etna_ra_setup(compiler); diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c index 61bc726c422..989c6efc56a 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.c @@ -375,6 +375,8 @@ get_src(struct etna_compile *c, nir_src *src) case nir_intrinsic_load_uniform: case nir_intrinsic_load_ubo: case nir_intrinsic_load_reg: + case nir_intrinsic_ddx: + case nir_intrinsic_ddy: return ra_src(c, src); case nir_intrinsic_load_front_face: return (hw_src) { .use = 1, .rgroup = ISA_REG_GROUP_INTERNAL }; @@ -575,6 +577,42 @@ emit_intrinsic(struct etna_compile *c, nir_intrinsic_instr * intr) case nir_intrinsic_terminate: etna_emit_discard(c, SRC_DISABLE); break; + case nir_intrinsic_ddx: { + unsigned dst_swiz; + struct etna_inst_dst dst = ra_def(c, &intr->def, &dst_swiz); + struct etna_inst_src src = get_src(c, &intr->src[0]); + + src = src_swizzle(src, dst_swiz); + + struct etna_inst inst = { + .dst = dst, + .opcode = ISA_OPC_DSX, + .cond = ISA_COND_TRUE, + .type = ISA_TYPE_F32, + .src[0] = src, + .src[1] = src, + }; + + emit_inst(c, &inst); + } break; + case nir_intrinsic_ddy: { + unsigned dst_swiz; + struct etna_inst_dst dst = ra_def(c, &intr->def, &dst_swiz); + struct etna_inst_src src = get_src(c, &intr->src[0]); + + src = src_swizzle(src, dst_swiz); + + struct etna_inst inst = { + .dst = dst, + .opcode = ISA_OPC_DSY, + .type = ISA_TYPE_F32, + .cond = ISA_COND_TRUE, + .src[0] = src, + .src[1] = src, + }; + + emit_inst(c, &inst); + } break; case nir_intrinsic_load_uniform: { unsigned dst_swiz; struct etna_inst_dst dst = ra_def(c, &intr->def, &dst_swiz); diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.h b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.h index 37785922082..c1041a3c714 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.h +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir.h @@ -296,7 +296,9 @@ def_for_instr(nir_instr *instr) intr->intrinsic == nir_intrinsic_load_instance_id || intr->intrinsic == nir_intrinsic_load_vertex_id || intr->intrinsic == nir_intrinsic_load_texture_scale || - intr->intrinsic == nir_intrinsic_load_texture_size_etna) + intr->intrinsic == nir_intrinsic_load_texture_size_etna || + intr->intrinsic == nir_intrinsic_ddx || + intr->intrinsic == nir_intrinsic_ddy) def = &intr->def; } break; case nir_instr_type_deref: diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.c b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.c index e745f5873ac..08a5ab5fb7b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_emit.c @@ -60,7 +60,6 @@ static const struct etna_op_info etna_ops[] = { OPC(seq, SET, EQ), OPC(sne, SET, NE), OPC(sge, SET, GE), OPC(slt, SET, LT), OPC(fcsel, SELECT, NZ), OP(fdiv, DIV), - OP(fddx, DSX), OP(fddy, DSY), /* type convert */ IOP(i2f32, I2F), @@ -159,10 +158,6 @@ etna_emit_alu(struct etna_compile *c, nir_op op, struct etna_inst_dst dst, inst.src[1].swiz = inst_swiz_compose(src[1].swiz, swiz_scalar); break; /* deal with instructions which don't have 1:1 mapping */ - case nir_op_fddx: - case nir_op_fddy: - inst.src[1] = src[0]; - break; case nir_op_fmin: case nir_op_fmax: case nir_op_imin: