From: Michael Tretter <m.tret...@pengutronix.de> Start emitting ALU instructions for nir_alu_instr structures from the NIR shader's main function implementation.
Signed-off-by: Michael Tretter <m.tret...@pengutronix.de> Signed-off-by: Philipp Zabel <p.za...@pengutronix.de> --- .../drivers/etnaviv/etnaviv_compiler.c | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c b/src/gallium/drivers/etnaviv/etnaviv_compiler.c index 59caff435e64..129c9115e783 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c @@ -1937,6 +1937,293 @@ etna_compile_pass_generate_code(struct etna_compile *c) tgsi_parse_free(&ctx); } +static void +translate_alu_sources(struct etna_compile *c, struct nir_alu_instr *instr, + struct etna_inst_src src[3]) +{ + const nir_op_info *info = &nir_op_infos[instr->op]; + + for (unsigned i = 0; i < info->num_inputs; i++) { + nir_alu_src nir_src = instr->src[i]; + if (nir_src.src.is_ssa) { + nir_const_value *val = NULL; + if (nir_src.src.ssa->parent_instr->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(nir_src.src.ssa->parent_instr); + // int indirect_offset = intr->src[0]; + src[i].use = 1; + src[i].swiz = INST_SWIZ(nir_src.swizzle[0], nir_src.swizzle[1], + nir_src.swizzle[2], nir_src.swizzle[3]); + src[i].reg = nir_intrinsic_base(intr); + src[i].rgroup = INST_RGROUP_UNIFORM_0; + } else { + val = nir_src_as_const_value(nir_src.src); + src[i] = alloc_imm_vec4u(c, ETNA_IMMEDIATE_CONSTANT, val->u32); + src[i].swiz = INST_SWIZ(nir_src.swizzle[0], nir_src.swizzle[1], + nir_src.swizzle[2], nir_src.swizzle[3]); + } + } else { + src[i].use = 1; + src[i].swiz = INST_SWIZ(nir_src.swizzle[0], nir_src.swizzle[1], + nir_src.swizzle[2], nir_src.swizzle[3]); + src[i].rgroup = INST_RGROUP_TEMP; + src[i].reg = nir_src.src.reg.reg->index; + src[i].amode = INST_AMODE_DIRECT; + src[i].neg = nir_src.negate; + } + } +} + +static void +etna_emit_alu(struct etna_compile *c, nir_alu_instr *instr) +{ + const nir_op_info *info = &nir_op_infos[instr->op]; + + struct etna_inst_dst dst; + struct etna_inst_src src[3] = {}; + + nir_alu_dest nir_dest = instr->dest; + + dst.use = 1; + dst.reg = nir_dest.dest.reg.reg->index; + dst.comps = nir_dest.write_mask; + + translate_alu_sources(c, instr, src); + + switch (instr->op) { + case nir_op_fceil: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_CEIL, + .dst = dst, + .src[2] = src[0], + }); + break; + case nir_op_ffloor: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_FLOOR, + .dst = dst, + .src[2] = src[0], + }); + break; + case nir_op_fmov: + case nir_op_imov: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_MOV, + .dst = dst, + .src[2] = src[0], + }); + break; + case nir_op_frcp: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_RCP, + .dst = dst, + .src[2] = src[0], + }); + break; + case nir_op_frsq: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_RSQ, + .dst = dst, + .src[2] = src[0], + }); + break; + case nir_op_fmul: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_MUL, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + }); + break; + case nir_op_fadd: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_ADD, + .dst = dst, + .src[0] = src[0], + .src[2] = src[1], + }); + break; + case nir_op_fdot2: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_DP2, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + }); + break; + case nir_op_fdot3: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_DP3, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + }); + break; + case nir_op_ffma: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_MAD, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + .src[2] = src[2], + }); + break; + case nir_op_fmin: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_SELECT, + .cond = INST_CONDITION_GT, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + .src[2] = src[0], + }); + break; + case nir_op_fmax: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_SELECT, + .cond = INST_CONDITION_LT, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + .src[2] = src[0], + }); + break; + case nir_op_ffract: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_FRC, + .dst = dst, + .src[2] = src[0], + }); + break; + case nir_op_fsqrt: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_SQRT, + .dst = dst, + .src[2] = src[0], + }); + break; + case nir_op_fexp2: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_EXP, + .dst = dst, + .src[2] = src[0], + }); + break; + case nir_op_seq: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_SET, + .cond = INST_CONDITION_EQ, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + }); + break; + case nir_op_sge: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_SET, + .cond = INST_CONDITION_GE, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + }); + break; + case nir_op_slt: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_SET, + .cond = INST_CONDITION_LT, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + }); + break; + case nir_op_sne: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_SET, + .cond = INST_CONDITION_NE, + .dst = dst, + .src[0] = src[0], + .src[1] = src[1], + }); + break; + default: + BUG("Unhandled nir_alu_instr: %s\n", info->name); + assert(0); + break; + } + + return; +} + +static void +etna_emit_intr(struct etna_compile *c, nir_intrinsic_instr *intr) +{ + switch (intr->intrinsic) { + case nir_intrinsic_nop: + emit_inst(c, &(struct etna_inst) { + .opcode = INST_OPCODE_NOP, + }); + break; + default: + /* Nothing to do */ + break; + } +} + +static void +etna_emit_instr(struct etna_compile *c, nir_instr *instr) +{ + switch (instr->type) { + case nir_instr_type_alu: + etna_emit_alu(c, nir_instr_as_alu(instr)); + break; + case nir_instr_type_intrinsic: + etna_emit_intr(c, nir_instr_as_intrinsic(instr)); + break; + case nir_instr_type_load_const: + /* Nothing to do */ + break; + default: + BUG("Unhandled nir_instr: %d", instr->type); + assert(0); + break; + } +} + +static void +etna_emit_block(struct etna_compile *c, nir_block *nblock) +{ + nir_foreach_instr(instr, nblock) { + etna_emit_instr(c, instr); + } +} + +static void +etna_emit_cf_list(struct etna_compile *c, struct exec_list *list) +{ + foreach_list_typed(nir_cf_node, node, node, list) { + switch (node->type) { + case nir_cf_node_block: + etna_emit_block(c, nir_cf_node_as_block(node)); + break; + default: + BUG("Unhandled nir node type %d\n", node->type); + assert(0); + break; + } + } +} + +static void +etna_emit_function(struct etna_compile *c, nir_function_impl *func_impl) +{ + /* Handle only main function */ + assert(strcmp(func_impl->function->name, "main") == 0); + + etna_emit_cf_list(c, &func_impl->body); + etna_emit_block(c, func_impl->end_block); + + return; +} + static void etna_setup_registers_from_nir(struct etna_compile *c, struct etna_shader_variant *v) { @@ -2117,6 +2404,9 @@ etna_compile_shader_nir(struct etna_compile *c, struct etna_shader_variant *v) etna_setup_uniforms_from_nir(c, v); etna_setup_inputs_from_nir(c, v); etna_setup_outputs_from_nir(c, v); + + impl = nir_shader_get_entrypoint(c->s); + etna_emit_function(c, impl); } /* Look up register by semantic */ -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev