X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fvc4%2Fvc4_qir.c;h=982e8298ae90b3c3b6cad55fb6713e5a85c0fe23;hb=ee69cfd11d34e6570c579c42f9cd8b5c8ea36bcf;hp=5d5ba1f0e13373936872b6f85138cf57c979679a;hpb=ac772b24a18bddc490dae171441795dedd85d7b2;p=mesa.git diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c index 5d5ba1f0e13..982e8298ae9 100644 --- a/src/gallium/drivers/vc4/vc4_qir.c +++ b/src/gallium/drivers/vc4/vc4_qir.c @@ -83,6 +83,8 @@ static const struct qir_op_info qir_op_info[] = { [QOP_TEX_RESULT] = { "tex_result", 1, 0, true }, [QOP_LOAD_IMM] = { "load_imm", 0, 1 }, + + [QOP_BRANCH] = { "branch", 0, 0, true }, }; static const char * @@ -204,8 +206,12 @@ qir_is_tex(struct qinst *inst) bool qir_depends_on_flags(struct qinst *inst) { - return (inst->cond != QPU_COND_ALWAYS && - inst->cond != QPU_COND_NEVER); + if (inst->op == QOP_BRANCH) { + return inst->cond != QPU_COND_BRANCH_ALWAYS; + } else { + return (inst->cond != QPU_COND_ALWAYS && + inst->cond != QPU_COND_NEVER); + } } bool @@ -224,6 +230,53 @@ qir_writes_r4(struct qinst *inst) } } +uint8_t +qir_channels_written(struct qinst *inst) +{ + if (qir_is_mul(inst)) { + switch (inst->dst.pack) { + case QPU_PACK_MUL_NOP: + case QPU_PACK_MUL_8888: + return 0xf; + case QPU_PACK_MUL_8A: + return 0x1; + case QPU_PACK_MUL_8B: + return 0x2; + case QPU_PACK_MUL_8C: + return 0x4; + case QPU_PACK_MUL_8D: + return 0x8; + } + } else { + switch (inst->dst.pack) { + case QPU_PACK_A_NOP: + case QPU_PACK_A_8888: + case QPU_PACK_A_8888_SAT: + case QPU_PACK_A_32_SAT: + return 0xf; + case QPU_PACK_A_8A: + case QPU_PACK_A_8A_SAT: + return 0x1; + case QPU_PACK_A_8B: + case QPU_PACK_A_8B_SAT: + return 0x2; + case QPU_PACK_A_8C: + case QPU_PACK_A_8C_SAT: + return 0x4; + case QPU_PACK_A_8D: + case QPU_PACK_A_8D_SAT: + return 0x8; + case QPU_PACK_A_16A: + case QPU_PACK_A_16A_SAT: + return 0x3; + case QPU_PACK_A_16B: + case QPU_PACK_A_16B_SAT: + return 0xc; + } + } + unreachable("Bad pack field"); +} + static void qir_print_reg(struct vc4_compile *c, struct qreg reg, bool write) { @@ -290,20 +343,26 @@ void qir_dump_inst(struct vc4_compile *c, struct qinst *inst) { fprintf(stderr, "%s", qir_get_op_name(inst->op)); - vc4_qpu_disasm_cond(stderr, inst->cond); + if (inst->op == QOP_BRANCH) + vc4_qpu_disasm_cond_branch(stderr, inst->cond); + else + vc4_qpu_disasm_cond(stderr, inst->cond); if (inst->sf) fprintf(stderr, ".sf"); fprintf(stderr, " "); - qir_print_reg(c, inst->dst, true); - if (inst->dst.pack) { + if (inst->op != QOP_BRANCH) { + qir_print_reg(c, inst->dst, true); if (inst->dst.pack) { - if (qir_is_mul(inst)) - vc4_qpu_disasm_pack_mul(stderr, inst->dst.pack); - else - vc4_qpu_disasm_pack_a(stderr, inst->dst.pack); + if (inst->dst.pack) { + if (qir_is_mul(inst)) + vc4_qpu_disasm_pack_mul(stderr, inst->dst.pack); + else + vc4_qpu_disasm_pack_a(stderr, inst->dst.pack); + } } } + for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { fprintf(stderr, ", "); qir_print_reg(c, inst->src[i], false); @@ -314,9 +373,65 @@ qir_dump_inst(struct vc4_compile *c, struct qinst *inst) void qir_dump(struct vc4_compile *c) { - list_for_each_entry(struct qinst, inst, &c->instructions, link) { - qir_dump_inst(c, inst); - fprintf(stderr, "\n"); + int ip = 0; + + qir_for_each_block(block, c) { + fprintf(stderr, "BLOCK %d:\n", block->index); + qir_for_each_inst(inst, block) { + if (c->temp_start) { + bool first = true; + + for (int i = 0; i < c->num_temps; i++) { + if (c->temp_start[i] != ip) + continue; + + if (first) { + first = false; + } else { + fprintf(stderr, ", "); + } + fprintf(stderr, "S%4d", i); + } + + if (first) + fprintf(stderr, " "); + else + fprintf(stderr, " "); + } + + if (c->temp_end) { + bool first = true; + + for (int i = 0; i < c->num_temps; i++) { + if (c->temp_end[i] != ip) + continue; + + if (first) { + first = false; + } else { + fprintf(stderr, ", "); + } + fprintf(stderr, "E%4d", i); + } + + if (first) + fprintf(stderr, " "); + else + fprintf(stderr, " "); + } + + qir_dump_inst(c, inst); + fprintf(stderr, "\n"); + ip++; + } + if (block->successors[1]) { + fprintf(stderr, "-> BLOCK %d, %d\n", + block->successors[0]->index, + block->successors[1]->index); + } else if (block->successors[0]) { + fprintf(stderr, "-> BLOCK %d\n", + block->successors[0]->index); + } } } @@ -379,7 +494,7 @@ qir_inst4(enum qop op, struct qreg dst, static void qir_emit(struct vc4_compile *c, struct qinst *inst) { - list_addtail(&inst->link, &c->instructions); + list_addtail(&inst->link, &c->cur_block->instructions); } /* Updates inst to write to a new temporary, emits it, and notes the def. */ @@ -415,12 +530,60 @@ qir_reg_equals(struct qreg a, struct qreg b) return a.file == b.file && a.index == b.index && a.pack == b.pack; } +struct qblock * +qir_new_block(struct vc4_compile *c) +{ + struct qblock *block = rzalloc(c, struct qblock); + + list_inithead(&block->instructions); + + block->predecessors = _mesa_set_create(block, + _mesa_hash_pointer, + _mesa_key_pointer_equal); + + block->index = c->next_block_index++; + + return block; +} + +void +qir_set_emit_block(struct vc4_compile *c, struct qblock *block) +{ + c->cur_block = block; + list_addtail(&block->link, &c->blocks); +} + +struct qblock * +qir_entry_block(struct vc4_compile *c) +{ + return list_first_entry(&c->blocks, struct qblock, link); +} + +struct qblock * +qir_exit_block(struct vc4_compile *c) +{ + return list_last_entry(&c->blocks, struct qblock, link); +} + +void +qir_link_blocks(struct qblock *predecessor, struct qblock *successor) +{ + _mesa_set_add(successor->predecessors, predecessor); + if (predecessor->successors[0]) { + assert(!predecessor->successors[1]); + predecessor->successors[1] = successor; + } else { + predecessor->successors[0] = successor; + } +} + struct vc4_compile * qir_compile_init(void) { struct vc4_compile *c = rzalloc(NULL, struct vc4_compile); - list_inithead(&c->instructions); + list_inithead(&c->blocks); + qir_set_emit_block(c, qir_new_block(c)); c->output_position_index = -1; c->output_color_index = -1; @@ -466,10 +629,13 @@ qir_follow_movs(struct vc4_compile *c, struct qreg reg) void qir_compile_destroy(struct vc4_compile *c) { - while (!list_empty(&c->instructions)) { - struct qinst *qinst = - (struct qinst *)c->instructions.next; - qir_remove_instruction(c, qinst); + qir_for_each_block(block, c) { + while (!list_empty(&block->instructions)) { + struct qinst *qinst = + list_first_entry(&block->instructions, + struct qinst, link); + qir_remove_instruction(c, qinst); + } } ralloc_free(c); @@ -523,8 +689,9 @@ void qir_SF(struct vc4_compile *c, struct qreg src) { struct qinst *last_inst = NULL; - if (!list_empty(&c->instructions)) - last_inst = (struct qinst *)c->instructions.prev; + + if (!list_empty(&c->cur_block->instructions)) + last_inst = (struct qinst *)c->cur_block->instructions.prev; /* We don't have any way to guess which kind of MOV is implied. */ assert(!src.pack); @@ -533,7 +700,7 @@ qir_SF(struct vc4_compile *c, struct qreg src) !c->defs[src.index] || last_inst != c->defs[src.index]) { last_inst = qir_MOV_dest(c, qir_reg(QFILE_NULL, 0), src); - last_inst = (struct qinst *)c->instructions.prev; + last_inst = (struct qinst *)c->cur_block->instructions.prev; } last_inst->sf = true; }