diff options
Diffstat (limited to 'src/gallium/drivers/r600/r600_asm.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_asm.c | 577 |
1 files changed, 376 insertions, 201 deletions
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 72c11dc44eb..6b1ad65b60f 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -1160,7 +1160,7 @@ static int r600_bytecode_alloc_kcache_lines(struct r600_bytecode *bc, struct r60 if ((r = r600_bytecode_add_cf(bc))) { return r; } - bc->cf_last->inst = (type << 3); + bc->cf_last->inst = type; kcache = bc->cf_last->kcache; } @@ -1248,10 +1248,10 @@ int r600_bytecode_add_alu_type(struct r600_bytecode *bc, const struct r600_bytec return -ENOMEM; memcpy(nalu, alu, sizeof(struct r600_bytecode_alu)); - if (bc->cf_last != NULL && bc->cf_last->inst != (type << 3)) { + if (bc->cf_last != NULL && bc->cf_last->inst != type) { /* check if we could add it anyway */ - if (bc->cf_last->inst == (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) && - type == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE) { + if (bc->cf_last->inst == BC_INST(bc, V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) && + type == BC_INST(bc, V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE)) { LIST_FOR_EACH_ENTRY(lalu, &bc->cf_last->alu, list) { if (lalu->predicate) { bc->force_add_cf = 1; @@ -1270,7 +1270,7 @@ int r600_bytecode_add_alu_type(struct r600_bytecode *bc, const struct r600_bytec return r; } } - bc->cf_last->inst = (type << 3); + bc->cf_last->inst = type; /* Check AR usage and load it if required */ for (i = 0; i < 3; i++) @@ -1377,17 +1377,21 @@ static unsigned r600_bytecode_num_tex_and_vtx_instructions(const struct r600_byt } } -static inline boolean last_inst_was_vtx_fetch(struct r600_bytecode *bc) +static inline boolean last_inst_was_not_vtx_fetch(struct r600_bytecode *bc) { - if (bc->chip_class == CAYMAN) { - if (bc->cf_last->inst != CM_V_SQ_CF_WORD1_SQ_CF_INST_TC) - return TRUE; - } else { - if (bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX && - bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC) - return TRUE; + switch (bc->chip_class) { + case R700: + case R600: + return bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX && + bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC; + case EVERGREEN: + return bc->cf_last->inst != EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX; + case CAYMAN: + return bc->cf_last->inst != CM_V_SQ_CF_WORD1_SQ_CF_INST_TC; + default: + R600_ERR("Unknown chip class %d.\n", bc->chip_class); + return FALSE; } - return FALSE; } int r600_bytecode_add_vtx(struct r600_bytecode *bc, const struct r600_bytecode_vtx *vtx) @@ -1401,17 +1405,28 @@ int r600_bytecode_add_vtx(struct r600_bytecode *bc, const struct r600_bytecode_v /* cf can contains only alu or only vtx or only tex */ if (bc->cf_last == NULL || - last_inst_was_vtx_fetch(bc) || + last_inst_was_not_vtx_fetch(bc) || bc->force_add_cf) { r = r600_bytecode_add_cf(bc); if (r) { free(nvtx); return r; } - if (bc->chip_class == CAYMAN) - bc->cf_last->inst = CM_V_SQ_CF_WORD1_SQ_CF_INST_TC; - else + switch (bc->chip_class) { + case R600: + case R700: bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_VTX; + break; + case EVERGREEN: + bc->cf_last->inst = EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX; + break; + case CAYMAN: + bc->cf_last->inst = CM_V_SQ_CF_WORD1_SQ_CF_INST_TC; + break; + default: + R600_ERR("Unknown chip class %d.\n", bc->chip_class); + return -EINVAL; + } } LIST_ADDTAIL(&nvtx->list, &bc->cf_last->vtx); /* each fetch use 4 dwords */ @@ -1433,7 +1448,7 @@ int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_t /* we can't fetch data und use it as texture lookup address in the same TEX clause */ if (bc->cf_last != NULL && - bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_TEX) { + bc->cf_last->inst == BC_INST(bc, V_SQ_CF_WORD1_SQ_CF_INST_TEX)) { struct r600_bytecode_tex *ttex; LIST_FOR_EACH_ENTRY(ttex, &bc->cf_last->tex, list) { if (ttex->dst_gpr == ntex->src_gpr) { @@ -1448,14 +1463,14 @@ int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_t /* cf can contains only alu or only vtx or only tex */ if (bc->cf_last == NULL || - bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_TEX || + bc->cf_last->inst != BC_INST(bc, V_SQ_CF_WORD1_SQ_CF_INST_TEX) || bc->force_add_cf) { r = r600_bytecode_add_cf(bc); if (r) { free(ntex); return r; } - bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX; + bc->cf_last->inst = BC_INST(bc, V_SQ_CF_WORD1_SQ_CF_INST_TEX); } if (ntex->src_gpr >= bc->ngpr) { bc->ngpr = ntex->src_gpr + 1; @@ -1593,7 +1608,7 @@ static int r600_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecod static void r600_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_cf *cf) { *bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1); - *bytecode++ = S_SQ_CF_WORD1_CF_INST(cf->inst) | + *bytecode++ = cf->inst | S_SQ_CF_WORD1_BARRIER(1) | S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1); } @@ -1604,16 +1619,16 @@ static int r600_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode unsigned id = cf->id; switch (cf->inst) { - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3): + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER: bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) | S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) | S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) | S_SQ_CF_ALU_WORD0_KCACHE_BANK1(cf->kcache[1].bank); - bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) | + bc->bytecode[id++] = cf->inst | S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache[1].mode) | S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) | S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) | @@ -1641,7 +1656,7 @@ static int r600_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) | S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) | S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) | - S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst) | + cf->output.inst | S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program); break; case V_SQ_CF_WORD1_SQ_CF_INST_JUMP: @@ -1654,7 +1669,7 @@ static int r600_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1); - bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) | + bc->bytecode[id++] = cf->inst | S_SQ_CF_WORD1_BARRIER(1) | S_SQ_CF_WORD1_COND(cf->cond) | S_SQ_CF_WORD1_POP_COUNT(cf->pop_count); @@ -1688,38 +1703,64 @@ int r600_bytecode_build(struct r600_bytecode *bc) /* addr start after all the CF instructions */ addr = bc->cf_last->id + 2; LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { - switch (cf->inst) { - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): - break; - case V_SQ_CF_WORD1_SQ_CF_INST_TEX: - case V_SQ_CF_WORD1_SQ_CF_INST_VTX: - case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: - /* fetch node need to be 16 bytes aligned*/ - addr += 3; - addr &= 0xFFFFFFFCUL; - break; - case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: - case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: - case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: - case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: - break; - case V_SQ_CF_WORD1_SQ_CF_INST_JUMP: - case V_SQ_CF_WORD1_SQ_CF_INST_ELSE: - case V_SQ_CF_WORD1_SQ_CF_INST_POP: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: - case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: - case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: - case CM_V_SQ_CF_WORD1_SQ_CF_INST_END: - break; - default: - R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); - return -EINVAL; + if (bc->chip_class >= EVERGREEN) { + switch (cf->inst) { + case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX: + /* fetch node need to be 16 bytes aligned*/ + addr += 3; + addr &= 0xFFFFFFFCUL; + break; + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE: + case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_POP: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN: + case CM_V_SQ_CF_WORD1_SQ_CF_INST_END: + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; + } + } else { + switch (cf->inst) { + case V_SQ_CF_WORD1_SQ_CF_INST_TEX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + /* fetch node need to be 16 bytes aligned*/ + addr += 3; + addr &= 0xFFFFFFFCUL; + break; + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + case V_SQ_CF_WORD1_SQ_CF_INST_JUMP: + case V_SQ_CF_WORD1_SQ_CF_INST_ELSE: + case V_SQ_CF_WORD1_SQ_CF_INST_POP: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; + } } cf->addr = addr; addr += cf->ndw; @@ -1731,92 +1772,158 @@ int r600_bytecode_build(struct r600_bytecode *bc) return -ENOMEM; LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { addr = cf->addr; - if (bc->chip_class >= EVERGREEN) + if (bc->chip_class >= EVERGREEN) { r = eg_bytecode_cf_build(bc, cf); - else - r = r600_bytecode_cf_build(bc, cf); - if (r) - return r; - switch (cf->inst) { - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): - nliteral = 0; - memset(literal, 0, sizeof(literal)); - LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { - r = r600_bytecode_alu_nliterals(bc, alu, literal, &nliteral); - if (r) - return r; - r600_bytecode_alu_adjust_literals(bc, alu, literal, nliteral); - switch(bc->chip_class) { - case R600: - r = r600_bytecode_alu_build(bc, alu, addr); - break; - case R700: - case EVERGREEN: /* eg alu is same encoding as r700 */ - case CAYMAN: /* eg alu is same encoding as r700 */ - r = r700_bytecode_alu_build(bc, alu, addr); - break; - default: - R600_ERR("unknown chip class %d.\n", bc->chip_class); - return -EINVAL; + if (r) + return r; + + switch (cf->inst) { + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE: + nliteral = 0; + memset(literal, 0, sizeof(literal)); + LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { + r = r600_bytecode_alu_nliterals(bc, alu, literal, &nliteral); + if (r) + return r; + r600_bytecode_alu_adjust_literals(bc, alu, literal, nliteral); + switch(bc->chip_class) { + case EVERGREEN: /* eg alu is same encoding as r700 */ + case CAYMAN: + r = r700_bytecode_alu_build(bc, alu, addr); + break; + default: + R600_ERR("unknown chip class %d.\n", bc->chip_class); + return -EINVAL; + } + if (r) + return r; + addr += 2; + if (alu->last) { + for (i = 0; i < align(nliteral, 2); ++i) { + bc->bytecode[addr++] = literal[i]; + } + nliteral = 0; + memset(literal, 0, sizeof(literal)); + } } - if (r) - return r; - addr += 2; - if (alu->last) { - for (i = 0; i < align(nliteral, 2); ++i) { - bc->bytecode[addr++] = literal[i]; + break; + case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX: + LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) { + r = r600_bytecode_vtx_build(bc, vtx, addr); + if (r) + return r; + addr += 4; + } + break; + case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX: + if (bc->chip_class == CAYMAN) { + LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) { + r = r600_bytecode_vtx_build(bc, vtx, addr); + if (r) + return r; + addr += 4; } - nliteral = 0; - memset(literal, 0, sizeof(literal)); } + LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) { + r = r600_bytecode_tex_build(bc, tex, addr); + if (r) + return r; + addr += 4; + } + break; + case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_POP: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN: + case CM_V_SQ_CF_WORD1_SQ_CF_INST_END: + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; } - break; - case V_SQ_CF_WORD1_SQ_CF_INST_VTX: - case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: - LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) { - r = r600_bytecode_vtx_build(bc, vtx, addr); - if (r) - return r; - addr += 4; - } - break; - case V_SQ_CF_WORD1_SQ_CF_INST_TEX: - if (bc->chip_class == CAYMAN) { + } else { + r = r600_bytecode_cf_build(bc, cf); + if (r) + return r; + + switch (cf->inst) { + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE: + nliteral = 0; + memset(literal, 0, sizeof(literal)); + LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { + r = r600_bytecode_alu_nliterals(bc, alu, literal, &nliteral); + if (r) + return r; + r600_bytecode_alu_adjust_literals(bc, alu, literal, nliteral); + switch(bc->chip_class) { + case R600: + r = r600_bytecode_alu_build(bc, alu, addr); + break; + case R700: + r = r700_bytecode_alu_build(bc, alu, addr); + break; + default: + R600_ERR("unknown chip class %d.\n", bc->chip_class); + return -EINVAL; + } + if (r) + return r; + addr += 2; + if (alu->last) { + for (i = 0; i < align(nliteral, 2); ++i) { + bc->bytecode[addr++] = literal[i]; + } + nliteral = 0; + memset(literal, 0, sizeof(literal)); + } + } + break; + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) { r = r600_bytecode_vtx_build(bc, vtx, addr); if (r) return r; addr += 4; } + break; + case V_SQ_CF_WORD1_SQ_CF_INST_TEX: + LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) { + r = r600_bytecode_tex_build(bc, tex, addr); + if (r) + return r; + addr += 4; + } + break; + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case V_SQ_CF_WORD1_SQ_CF_INST_JUMP: + case V_SQ_CF_WORD1_SQ_CF_INST_ELSE: + case V_SQ_CF_WORD1_SQ_CF_INST_POP: + case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; } - LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) { - r = r600_bytecode_tex_build(bc, tex, addr); - if (r) - return r; - addr += 4; - } - break; - case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: - case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: - case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: - case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: - case V_SQ_CF_WORD1_SQ_CF_INST_JUMP: - case V_SQ_CF_WORD1_SQ_CF_INST_ELSE: - case V_SQ_CF_WORD1_SQ_CF_INST_POP: - case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: - case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: - case CM_V_SQ_CF_WORD1_SQ_CF_INST_END: - break; - default: - R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); - return -EINVAL; } } return 0; @@ -1891,72 +1998,140 @@ void r600_bytecode_dump(struct r600_bytecode *bc) LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { id = cf->id; - switch (cf->inst) { - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3): - case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): - fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]); - fprintf(stderr, "ADDR:%d ", cf->addr); - fprintf(stderr, "KCACHE_MODE0:%X ", cf->kcache[0].mode); - fprintf(stderr, "KCACHE_BANK0:%X ", cf->kcache[0].bank); - fprintf(stderr, "KCACHE_BANK1:%X\n", cf->kcache[1].bank); - id++; - fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]); - fprintf(stderr, "INST:0x%x ", cf->inst); - fprintf(stderr, "KCACHE_MODE1:%X ", cf->kcache[1].mode); - fprintf(stderr, "KCACHE_ADDR0:%X ", cf->kcache[0].addr); - fprintf(stderr, "KCACHE_ADDR1:%X ", cf->kcache[1].addr); - fprintf(stderr, "COUNT:%d\n", cf->ndw / 2); - break; - case V_SQ_CF_WORD1_SQ_CF_INST_TEX: - case V_SQ_CF_WORD1_SQ_CF_INST_VTX: - case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: - fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]); - fprintf(stderr, "ADDR:%d\n", cf->addr); - id++; - fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]); - fprintf(stderr, "INST:0x%x ", cf->inst); - fprintf(stderr, "COUNT:%d\n", cf->ndw / 4); - break; - case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: - case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: - case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: - case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: - fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]); - fprintf(stderr, "GPR:%X ", cf->output.gpr); - fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size); - fprintf(stderr, "ARRAY_BASE:%X ", cf->output.array_base); - fprintf(stderr, "TYPE:%X\n", cf->output.type); - id++; - fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]); - fprintf(stderr, "SWIZ_X:%X ", cf->output.swizzle_x); - fprintf(stderr, "SWIZ_Y:%X ", cf->output.swizzle_y); - fprintf(stderr, "SWIZ_Z:%X ", cf->output.swizzle_z); - fprintf(stderr, "SWIZ_W:%X ", cf->output.swizzle_w); - fprintf(stderr, "BARRIER:%X ", cf->output.barrier); - fprintf(stderr, "INST:0x%x ", cf->output.inst); - fprintf(stderr, "BURST_COUNT:%d ", cf->output.burst_count); - fprintf(stderr, "EOP:%X\n", cf->output.end_of_program); - break; - case V_SQ_CF_WORD1_SQ_CF_INST_JUMP: - case V_SQ_CF_WORD1_SQ_CF_INST_ELSE: - case V_SQ_CF_WORD1_SQ_CF_INST_POP: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: - case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: - case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: - case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: - case CM_V_SQ_CF_WORD1_SQ_CF_INST_END: - fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]); - fprintf(stderr, "ADDR:%d\n", cf->cf_addr); - id++; - fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]); - fprintf(stderr, "INST:0x%x ", cf->inst); - fprintf(stderr, "COND:%X ", cf->cond); - fprintf(stderr, "POP_COUNT:%X\n", cf->pop_count); - break; + if (bc->chip_class >= EVERGREEN) { + switch (cf->inst) { + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER: + case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE: + fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]); + fprintf(stderr, "ADDR:%d ", cf->addr); + fprintf(stderr, "KCACHE_MODE0:%X ", cf->kcache[0].mode); + fprintf(stderr, "KCACHE_BANK0:%X ", cf->kcache[0].bank); + fprintf(stderr, "KCACHE_BANK1:%X\n", cf->kcache[1].bank); + id++; + fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]); + fprintf(stderr, "INST:0x%x ", EG_G_SQ_CF_ALU_WORD1_CF_INST(cf->inst)); + fprintf(stderr, "KCACHE_MODE1:%X ", cf->kcache[1].mode); + fprintf(stderr, "KCACHE_ADDR0:%X ", cf->kcache[0].addr); + fprintf(stderr, "KCACHE_ADDR1:%X ", cf->kcache[1].addr); + fprintf(stderr, "COUNT:%d\n", cf->ndw / 2); + break; + case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX: + fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]); + fprintf(stderr, "ADDR:%d\n", cf->addr); + id++; + fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]); + fprintf(stderr, "INST:0x%x ", EG_G_SQ_CF_WORD1_CF_INST(cf->inst)); + fprintf(stderr, "COUNT:%d\n", cf->ndw / 4); + break; + case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]); + fprintf(stderr, "GPR:%X ", cf->output.gpr); + fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size); + fprintf(stderr, "ARRAY_BASE:%X ", cf->output.array_base); + fprintf(stderr, "TYPE:%X\n", cf->output.type); + id++; + fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]); + fprintf(stderr, "SWIZ_X:%X ", cf->output.swizzle_x); + fprintf(stderr, "SWIZ_Y:%X ", cf->output.swizzle_y); + fprintf(stderr, "SWIZ_Z:%X ", cf->output.swizzle_z); + fprintf(stderr, "SWIZ_W:%X ", cf->output.swizzle_w); + fprintf(stderr, "BARRIER:%X ", cf->output.barrier); + fprintf(stderr, "INST:0x%x ", EG_G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst)); + fprintf(stderr, "BURST_COUNT:%d ", cf->output.burst_count); + fprintf(stderr, "EOP:%X\n", cf->output.end_of_program); + break; + case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_POP: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN: + case CM_V_SQ_CF_WORD1_SQ_CF_INST_END: + fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]); + fprintf(stderr, "ADDR:%d\n", cf->cf_addr); + id++; + fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]); + fprintf(stderr, "INST:0x%x ", EG_G_SQ_CF_WORD1_CF_INST(cf->inst)); + fprintf(stderr, "COND:%X ", cf->cond); + fprintf(stderr, "POP_COUNT:%X\n", cf->pop_count); + break; + default: + R600_ERR("Unknown instruction %0x\n", cf->inst); + } + } else { + switch (cf->inst) { + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER: + case V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE: + fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]); + fprintf(stderr, "ADDR:%d ", cf->addr); + fprintf(stderr, "KCACHE_MODE0:%X ", cf->kcache[0].mode); + fprintf(stderr, "KCACHE_BANK0:%X ", cf->kcache[0].bank); + fprintf(stderr, "KCACHE_BANK1:%X\n", cf->kcache[1].bank); + id++; + fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]); + fprintf(stderr, "INST:0x%x ", R600_G_SQ_CF_ALU_WORD1_CF_INST(cf->inst)); + fprintf(stderr, "KCACHE_MODE1:%X ", cf->kcache[1].mode); + fprintf(stderr, "KCACHE_ADDR0:%X ", cf->kcache[0].addr); + fprintf(stderr, "KCACHE_ADDR1:%X ", cf->kcache[1].addr); + fprintf(stderr, "COUNT:%d\n", cf->ndw / 2); + break; + case V_SQ_CF_WORD1_SQ_CF_INST_TEX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]); + fprintf(stderr, "ADDR:%d\n", cf->addr); + id++; + fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]); + fprintf(stderr, "INST:0x%x ", R600_G_SQ_CF_WORD1_CF_INST(cf->inst)); + fprintf(stderr, "COUNT:%d\n", cf->ndw / 4); + break; + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]); + fprintf(stderr, "GPR:%X ", cf->output.gpr); + fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size); + fprintf(stderr, "ARRAY_BASE:%X ", cf->output.array_base); + fprintf(stderr, "TYPE:%X\n", cf->output.type); + id++; + fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]); + fprintf(stderr, "SWIZ_X:%X ", cf->output.swizzle_x); + fprintf(stderr, "SWIZ_Y:%X ", cf->output.swizzle_y); + fprintf(stderr, "SWIZ_Z:%X ", cf->output.swizzle_z); + fprintf(stderr, "SWIZ_W:%X ", cf->output.swizzle_w); + fprintf(stderr, "BARRIER:%X ", cf->output.barrier); + fprintf(stderr, "INST:0x%x ", R600_G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst)); + fprintf(stderr, "BURST_COUNT:%d ", cf->output.burst_count); + fprintf(stderr, "EOP:%X\n", cf->output.end_of_program); + break; + case V_SQ_CF_WORD1_SQ_CF_INST_JUMP: + case V_SQ_CF_WORD1_SQ_CF_INST_ELSE: + case V_SQ_CF_WORD1_SQ_CF_INST_POP: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE: + case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK: + case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS: + case V_SQ_CF_WORD1_SQ_CF_INST_RETURN: + fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]); + fprintf(stderr, "ADDR:%d\n", cf->cf_addr); + id++; + fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]); + fprintf(stderr, "INST:0x%x ", R600_G_SQ_CF_WORD1_CF_INST(cf->inst)); + fprintf(stderr, "COND:%X ", cf->cond); + fprintf(stderr, "POP_COUNT:%X\n", cf->pop_count); + break; + default: + R600_ERR("Unknown instruction %0x\n", cf->inst); + } } id = cf->addr; |