r600: Emit EOP for more CF instruction types
So far on pre-cayman chipsets the CF instructions CF_OP_LOOP_END, CF_OP_CALL_FS, CF_OP_POP, and CF_OP_GDS an extra CF_NOP instruction was added to add the EOP flag, even though this is not actually needed, because all these instrutions support the EOP flag. This patch removes the fixup code, adds setting the EOP flag for the according instructions as well as others like CF_OP_TEX and CF_OP_VTX, and adds writing out EOP for this type of instruction in the disassembler. This also fixes a bug where shaders were created that didn't actually have the EOP flag set in the last CF instruction, which might have resulted in GPU lockups. [airlied: cleaned up a little] Signed-off-by: Gert Wollny <gw.fossdev@gmail.com> Cc: <mesa-stable@lists.freedesktop.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -71,10 +71,13 @@ int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf)
|
|||||||
} else if (cfop->flags & CF_CLAUSE) {
|
} else if (cfop->flags & CF_CLAUSE) {
|
||||||
/* CF_TEX/VTX (CF_ALU already handled above) */
|
/* CF_TEX/VTX (CF_ALU already handled above) */
|
||||||
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
|
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
|
||||||
bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(opcode) |
|
bc->bytecode[id] = S_SQ_CF_WORD1_CF_INST(opcode) |
|
||||||
S_SQ_CF_WORD1_BARRIER(1) |
|
S_SQ_CF_WORD1_BARRIER(1) |
|
||||||
S_SQ_CF_WORD1_VALID_PIXEL_MODE(cf->vpm) |
|
S_SQ_CF_WORD1_VALID_PIXEL_MODE(cf->vpm) |
|
||||||
S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
|
S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
|
||||||
|
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
|
||||||
|
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->end_of_program);
|
||||||
|
id++;
|
||||||
} else if (cfop->flags & CF_EXP) {
|
} else if (cfop->flags & CF_EXP) {
|
||||||
/* EXPORT instructions */
|
/* EXPORT instructions */
|
||||||
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
|
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
|
||||||
@@ -133,12 +136,14 @@ int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf)
|
|||||||
} else {
|
} else {
|
||||||
/* other instructions */
|
/* other instructions */
|
||||||
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
|
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
|
||||||
bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(opcode)|
|
bc->bytecode[id] = S_SQ_CF_WORD1_CF_INST(opcode) |
|
||||||
S_SQ_CF_WORD1_BARRIER(1) |
|
S_SQ_CF_WORD1_BARRIER(1) |
|
||||||
S_SQ_CF_WORD1_COND(cf->cond) |
|
S_SQ_CF_WORD1_COND(cf->cond) |
|
||||||
S_SQ_CF_WORD1_POP_COUNT(cf->pop_count) |
|
S_SQ_CF_WORD1_POP_COUNT(cf->pop_count) |
|
||||||
S_SQ_CF_WORD1_COUNT(cf->count) |
|
S_SQ_CF_WORD1_COUNT(cf->count);
|
||||||
S_SQ_CF_WORD1_END_OF_PROGRAM(cf->end_of_program);
|
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
|
||||||
|
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->end_of_program);
|
||||||
|
id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -1625,7 +1625,8 @@ static void r600_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_byt
|
|||||||
*bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
|
*bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
|
||||||
*bytecode++ = S_SQ_CF_WORD1_CF_INST(r600_isa_cf_opcode(ISA_CC_R600, cf->op)) |
|
*bytecode++ = S_SQ_CF_WORD1_CF_INST(r600_isa_cf_opcode(ISA_CC_R600, cf->op)) |
|
||||||
S_SQ_CF_WORD1_BARRIER(1) |
|
S_SQ_CF_WORD1_BARRIER(1) |
|
||||||
S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
|
S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1)|
|
||||||
|
S_SQ_CF_WORD1_END_OF_PROGRAM(cf->end_of_program);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* common for r600/r700 - eg in eg_asm.c */
|
/* common for r600/r700 - eg in eg_asm.c */
|
||||||
@@ -2097,6 +2098,8 @@ void r600_bytecode_disasm(struct r600_bytecode *bc)
|
|||||||
bc->bytecode[id + 1], cfop->name);
|
bc->bytecode[id + 1], cfop->name);
|
||||||
fprintf(stderr, "%d @%d ", cf->ndw / 4, cf->addr);
|
fprintf(stderr, "%d @%d ", cf->ndw / 4, cf->addr);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
if (cf->end_of_program)
|
||||||
|
fprintf(stderr, "EOP ");
|
||||||
} else if (cfop->flags & CF_EXP) {
|
} else if (cfop->flags & CF_EXP) {
|
||||||
int o = 0;
|
int o = 0;
|
||||||
const char *exp_type[] = {"PIXEL", "POS ", "PARAM"};
|
const char *exp_type[] = {"PIXEL", "POS ", "PARAM"};
|
||||||
|
@@ -3809,7 +3809,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
|||||||
last = r600_isa_cf(ctx.bc->cf_last->op);
|
last = r600_isa_cf(ctx.bc->cf_last->op);
|
||||||
|
|
||||||
/* alu clause instructions don't have EOP bit, so add NOP */
|
/* alu clause instructions don't have EOP bit, so add NOP */
|
||||||
if (!last || last->flags & CF_ALU || ctx.bc->cf_last->op == CF_OP_LOOP_END || ctx.bc->cf_last->op == CF_OP_CALL_FS || ctx.bc->cf_last->op == CF_OP_POP || ctx.bc->cf_last->op == CF_OP_GDS)
|
if (!last || last->flags & CF_ALU)
|
||||||
r600_bytecode_add_cfinst(ctx.bc, CF_OP_NOP);
|
r600_bytecode_add_cfinst(ctx.bc, CF_OP_NOP);
|
||||||
|
|
||||||
ctx.bc->cf_last->end_of_program = 1;
|
ctx.bc->cf_last->end_of_program = 1;
|
||||||
|
@@ -30,7 +30,8 @@ void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_c
|
|||||||
*bytecode++ = S_SQ_CF_WORD1_CF_INST(r600_isa_cf_opcode(ISA_CC_R700, cf->op)) |
|
*bytecode++ = S_SQ_CF_WORD1_CF_INST(r600_isa_cf_opcode(ISA_CC_R700, cf->op)) |
|
||||||
S_SQ_CF_WORD1_BARRIER(1) |
|
S_SQ_CF_WORD1_BARRIER(1) |
|
||||||
S_SQ_CF_WORD1_COUNT(count) |
|
S_SQ_CF_WORD1_COUNT(count) |
|
||||||
S_SQ_CF_WORD1_COUNT_3(count >> 3);
|
S_SQ_CF_WORD1_COUNT_3(count >> 3)|
|
||||||
|
S_SQ_CF_WORD1_END_OF_PROGRAM(cf->end_of_program);
|
||||||
}
|
}
|
||||||
|
|
||||||
int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *alu, unsigned id)
|
int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *alu, unsigned id)
|
||||||
|
Reference in New Issue
Block a user