mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 02:20:11 +01:00
r600g: use tables with ISA info v3
v3: added some flags including condition codes for ALU,
fixed issue with CF reverse lookup (overlapping ranges of CF_ALU_xxx
and other CF instructions)
rebased on current master
Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
This commit is contained in:
parent
b68a3b865b
commit
022122ee63
10 changed files with 2377 additions and 1788 deletions
|
|
@ -3,6 +3,7 @@ C_SOURCES = \
|
|||
r600_blit.c \
|
||||
r600_buffer.c \
|
||||
r600_hw_context.c \
|
||||
r600_isa.c \
|
||||
r600_pipe.c \
|
||||
r600_query.c \
|
||||
r600_resource.c \
|
||||
|
|
|
|||
|
|
@ -32,121 +32,94 @@ int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf)
|
|||
{
|
||||
unsigned id = cf->id;
|
||||
|
||||
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:
|
||||
/* prepend ALU_EXTENDED if we need more than 2 kcache sets */
|
||||
if (cf->eg_alu_extended) {
|
||||
bc->bytecode[id++] =
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE0(V_SQ_CF_INDEX_NONE) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE1(V_SQ_CF_INDEX_NONE) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE2(V_SQ_CF_INDEX_NONE) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE3(V_SQ_CF_INDEX_NONE) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK2(cf->kcache[2].bank) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK3(cf->kcache[3].bank) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_MODE2(cf->kcache[2].mode);
|
||||
bc->bytecode[id++] = EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_EXTENDED |
|
||||
S_SQ_CF_ALU_WORD1_EXT_KCACHE_MODE3(cf->kcache[3].mode) |
|
||||
S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR2(cf->kcache[2].addr) |
|
||||
S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR3(cf->kcache[3].addr) |
|
||||
S_SQ_CF_ALU_WORD1_EXT_BARRIER(1);
|
||||
}
|
||||
if (cf->op == CF_NATIVE) {
|
||||
bc->bytecode[id++] = cf->isa[0];
|
||||
bc->bytecode[id++] = cf->isa[1];
|
||||
} else {
|
||||
const struct cf_op_info *cfop = r600_isa_cf(cf->op);
|
||||
unsigned opcode = r600_isa_cf_opcode(bc->isa->hw_class, cf->op);
|
||||
if (cfop->flags & CF_ALU) { /* ALU clauses */
|
||||
|
||||
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++] = 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) |
|
||||
/* prepend ALU_EXTENDED if we need more than 2 kcache sets */
|
||||
if (cf->eg_alu_extended) {
|
||||
bc->bytecode[id++] =
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE0(V_SQ_CF_INDEX_NONE) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE1(V_SQ_CF_INDEX_NONE) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE2(V_SQ_CF_INDEX_NONE) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE3(V_SQ_CF_INDEX_NONE) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK2(cf->kcache[2].bank) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK3(cf->kcache[3].bank) |
|
||||
S_SQ_CF_ALU_WORD0_EXT_KCACHE_MODE2(cf->kcache[2].mode);
|
||||
bc->bytecode[id++] =
|
||||
S_SQ_CF_ALU_WORD1_EXT_CF_INST(
|
||||
r600_isa_cf_opcode(bc->isa->hw_class, CF_OP_ALU_EXT)) |
|
||||
S_SQ_CF_ALU_WORD1_EXT_KCACHE_MODE3(cf->kcache[3].mode) |
|
||||
S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR2(cf->kcache[2].addr) |
|
||||
S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR3(cf->kcache[3].addr) |
|
||||
S_SQ_CF_ALU_WORD1_EXT_BARRIER(1);
|
||||
}
|
||||
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(opcode) |
|
||||
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) |
|
||||
S_SQ_CF_ALU_WORD1_BARRIER(1) |
|
||||
S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
|
||||
break;
|
||||
case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX:
|
||||
case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX:
|
||||
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
|
||||
bc->bytecode[id++] = cf->inst |
|
||||
} else if (cfop->flags & CF_CLAUSE) {
|
||||
/* 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_WORD1_CF_INST(opcode) |
|
||||
S_SQ_CF_WORD1_BARRIER(1) |
|
||||
S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
|
||||
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:
|
||||
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
|
||||
bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
|
||||
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) |
|
||||
cf->output.inst;
|
||||
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
|
||||
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
|
||||
id++;
|
||||
break;
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF0:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF1:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF2:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF3:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF0:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF1:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF2:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF3:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF0:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF1:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF2:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF3:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF0:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF1:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF2:
|
||||
case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF3:
|
||||
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
|
||||
bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
|
||||
cf->output.inst |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(cf->output.comp_mask) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(cf->output.array_size);
|
||||
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
|
||||
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
|
||||
id++;
|
||||
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_START_DX10:
|
||||
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:
|
||||
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
|
||||
bc->bytecode[id++] = cf->inst |
|
||||
} else if (cfop->flags & CF_EXP) {
|
||||
/* EXPORT instructions */
|
||||
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
|
||||
bc->bytecode[id] =
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
|
||||
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(opcode);
|
||||
|
||||
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
|
||||
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
|
||||
id++;
|
||||
} else if (cfop->flags & CF_STRM) {
|
||||
/* MEM_STREAM instructions */
|
||||
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
|
||||
bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(opcode) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(cf->output.comp_mask) |
|
||||
S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(cf->output.array_size);
|
||||
if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
|
||||
bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
|
||||
id++;
|
||||
} else {
|
||||
/* branch, loop, call, return instructions */
|
||||
bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
|
||||
bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(opcode)|
|
||||
S_SQ_CF_WORD1_BARRIER(1) |
|
||||
S_SQ_CF_WORD1_COND(cf->cond) |
|
||||
S_SQ_CF_WORD1_POP_COUNT(cf->pop_count);
|
||||
break;
|
||||
case CF_NATIVE:
|
||||
bc->bytecode[id++] = cf->isa[0];
|
||||
bc->bytecode[id++] = cf->isa[1];
|
||||
break;
|
||||
default:
|
||||
R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1)
|
||||
void eg_bytecode_export_read(struct r600_bytecode *bc,
|
||||
struct r600_bytecode_output *output, uint32_t word0, uint32_t word1)
|
||||
{
|
||||
output->array_base = G_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(word0);
|
||||
output->type = G_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(word0);
|
||||
|
|
@ -159,7 +132,8 @@ void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0
|
|||
output->swizzle_w = G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(word1);
|
||||
output->burst_count = G_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(word1);
|
||||
output->end_of_program = G_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(word1);
|
||||
output->inst = EG_S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(word1));
|
||||
output->op = r600_isa_cf_by_opcode(bc->isa,
|
||||
G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(word1), /* is_cf_alu = */ 0 );
|
||||
output->barrier = G_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(word1);
|
||||
output->array_size = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(word1);
|
||||
output->comp_mask = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(word1);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -24,6 +24,7 @@
|
|||
#define R600_ASM_H
|
||||
|
||||
#include "r600_pipe.h"
|
||||
#include "r600_isa.h"
|
||||
|
||||
struct r600_bytecode_alu_src {
|
||||
unsigned sel;
|
||||
|
|
@ -47,7 +48,7 @@ struct r600_bytecode_alu {
|
|||
struct list_head list;
|
||||
struct r600_bytecode_alu_src src[3];
|
||||
struct r600_bytecode_alu_dst dst;
|
||||
unsigned inst;
|
||||
unsigned op;
|
||||
unsigned last;
|
||||
unsigned is_op3;
|
||||
unsigned execute_mask;
|
||||
|
|
@ -61,7 +62,7 @@ struct r600_bytecode_alu {
|
|||
|
||||
struct r600_bytecode_tex {
|
||||
struct list_head list;
|
||||
unsigned inst;
|
||||
unsigned op;
|
||||
unsigned inst_mod;
|
||||
unsigned resource_id;
|
||||
unsigned src_gpr;
|
||||
|
|
@ -89,7 +90,7 @@ struct r600_bytecode_tex {
|
|||
|
||||
struct r600_bytecode_vtx {
|
||||
struct list_head list;
|
||||
unsigned inst;
|
||||
unsigned op;
|
||||
unsigned fetch_type;
|
||||
unsigned buffer_id;
|
||||
unsigned src_gpr;
|
||||
|
|
@ -116,8 +117,7 @@ struct r600_bytecode_output {
|
|||
unsigned type;
|
||||
unsigned end_of_program;
|
||||
|
||||
/* CF_INST. This is already bit-shifted and only needs to be or'd for bytecode. */
|
||||
unsigned inst;
|
||||
unsigned op;
|
||||
|
||||
unsigned elem_size;
|
||||
unsigned gpr;
|
||||
|
|
@ -135,20 +135,10 @@ struct r600_bytecode_kcache {
|
|||
unsigned addr;
|
||||
};
|
||||
|
||||
/* A value of CF_NATIVE in r600_bytecode_cf::inst means that this instruction
|
||||
* has already been encoded, and the encoding has been stored in
|
||||
* r600_bytecode::isa. This is used by the LLVM backend to emit CF instructions
|
||||
* e.g. RAT_WRITE_* that can't be properly represented by struct
|
||||
* r600_bytecode_cf.
|
||||
*/
|
||||
#define CF_NATIVE ~0
|
||||
|
||||
struct r600_bytecode_cf {
|
||||
struct list_head list;
|
||||
|
||||
/* CF_INST. This is already bit-shifted and only needs to be or'd for bytecode. */
|
||||
unsigned inst;
|
||||
|
||||
unsigned op;
|
||||
unsigned addr;
|
||||
unsigned ndw;
|
||||
unsigned id;
|
||||
|
|
@ -216,6 +206,7 @@ struct r600_bytecode {
|
|||
unsigned ar_chan;
|
||||
unsigned ar_handling;
|
||||
unsigned r6xx_nop_after_rel_dst;
|
||||
struct r600_isa* isa;
|
||||
};
|
||||
|
||||
/* eg_asm.c */
|
||||
|
|
@ -227,16 +218,24 @@ void r600_bytecode_init(struct r600_bytecode *bc,
|
|||
enum radeon_family family,
|
||||
enum r600_msaa_texture_mode msaa_texture_mode);
|
||||
void r600_bytecode_clear(struct r600_bytecode *bc);
|
||||
int r600_bytecode_add_alu(struct r600_bytecode *bc, const struct r600_bytecode_alu *alu);
|
||||
int r600_bytecode_add_vtx(struct r600_bytecode *bc, const struct r600_bytecode_vtx *vtx);
|
||||
int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_tex *tex);
|
||||
int r600_bytecode_add_output(struct r600_bytecode *bc, const struct r600_bytecode_output *output);
|
||||
int r600_bytecode_add_alu(struct r600_bytecode *bc,
|
||||
const struct r600_bytecode_alu *alu);
|
||||
int r600_bytecode_add_vtx(struct r600_bytecode *bc,
|
||||
const struct r600_bytecode_vtx *vtx);
|
||||
int r600_bytecode_add_tex(struct r600_bytecode *bc,
|
||||
const struct r600_bytecode_tex *tex);
|
||||
int r600_bytecode_add_output(struct r600_bytecode *bc,
|
||||
const struct r600_bytecode_output *output);
|
||||
int r600_bytecode_build(struct r600_bytecode *bc);
|
||||
int r600_bytecode_add_cfinst(struct r600_bytecode *bc, int inst);
|
||||
int r600_bytecode_add_alu_type(struct r600_bytecode *bc, const struct r600_bytecode_alu *alu, int type);
|
||||
void r600_bytecode_special_constants(uint32_t value, unsigned *sel, unsigned *neg);
|
||||
int r600_bytecode_add_cfinst(struct r600_bytecode *bc,
|
||||
unsigned op);
|
||||
int r600_bytecode_add_alu_type(struct r600_bytecode *bc,
|
||||
const struct r600_bytecode_alu *alu, unsigned type);
|
||||
void r600_bytecode_special_constants(uint32_t value,
|
||||
unsigned *sel, unsigned *neg);
|
||||
void r600_bytecode_dump(struct r600_bytecode *bc);
|
||||
void r600_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
|
||||
void r600_bytecode_alu_read(struct r600_bytecode *bc,
|
||||
struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
|
||||
|
||||
int cm_bytecode_add_cf_end(struct r600_bytecode *bc);
|
||||
|
||||
|
|
@ -245,11 +244,16 @@ void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
|
|||
const struct pipe_vertex_element *elements);
|
||||
|
||||
/* r700_asm.c */
|
||||
void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_cf *cf);
|
||||
int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *alu, unsigned id);
|
||||
void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
|
||||
void r600_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
|
||||
void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
|
||||
void r700_bytecode_cf_vtx_build(uint32_t *bytecode,
|
||||
const struct r600_bytecode_cf *cf);
|
||||
int r700_bytecode_alu_build(struct r600_bytecode *bc,
|
||||
struct r600_bytecode_alu *alu, unsigned id);
|
||||
void r700_bytecode_alu_read(struct r600_bytecode *bc,
|
||||
struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1);
|
||||
void r600_bytecode_export_read(struct r600_bytecode *bc,
|
||||
struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
|
||||
void eg_bytecode_export_read(struct r600_bytecode *bc,
|
||||
struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
|
||||
|
||||
void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
|
||||
unsigned *num_format, unsigned *format_comp, unsigned *endian);
|
||||
|
|
|
|||
116
src/gallium/drivers/r600/r600_isa.c
Normal file
116
src/gallium/drivers/r600/r600_isa.c
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2012 Vadim Girlin <vadimgirlin@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Vadim Girlin
|
||||
*/
|
||||
|
||||
#include "r600_pipe.h"
|
||||
#include "r600_isa.h"
|
||||
|
||||
int r600_isa_init(struct r600_context *ctx, struct r600_isa *isa) {
|
||||
|
||||
assert(ctx->chip_class >= R600 && ctx->chip_class <= CAYMAN);
|
||||
isa->hw_class = ctx->chip_class - R600;
|
||||
|
||||
assert(isa->hw_class >= ISA_CC_R600 && isa->hw_class <= ISA_CC_EVERGREEN);
|
||||
|
||||
/* reverse lookup maps are required for bytecode parsing only,
|
||||
* currently it's needed for handling the bytestream from llvm backend */
|
||||
#if defined R600_USE_LLVM || defined HAVE_OPENCL
|
||||
unsigned i, use_llvm;
|
||||
|
||||
use_llvm = debug_get_bool_option("R600_LLVM", TRUE);
|
||||
|
||||
if (!use_llvm)
|
||||
return 0;
|
||||
|
||||
isa->alu_op2_map = calloc(256, sizeof(unsigned));
|
||||
if (!isa->alu_op2_map)
|
||||
return -1;
|
||||
isa->alu_op3_map = calloc(256, sizeof(unsigned));
|
||||
if (!isa->alu_op3_map)
|
||||
return -1;
|
||||
isa->fetch_map = calloc(256, sizeof(unsigned));
|
||||
if (!isa->fetch_map)
|
||||
return -1;
|
||||
isa->cf_map = calloc(256, sizeof(unsigned));
|
||||
if (!isa->cf_map)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < TABLE_SIZE(alu_op_table); ++i) {
|
||||
const struct alu_op_info *op = &alu_op_table[i];
|
||||
unsigned opc;
|
||||
if (op->flags & AF_LDS || op->slots[isa->hw_class] == 0)
|
||||
continue;
|
||||
opc = op->opcode[isa->hw_class >> 1];
|
||||
assert(opc != -1);
|
||||
if (op->src_count == 3)
|
||||
isa->alu_op3_map[opc] = i + 1;
|
||||
else
|
||||
isa->alu_op2_map[opc] = i + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < TABLE_SIZE(fetch_op_table); ++i) {
|
||||
const struct fetch_op_info *op = &fetch_op_table[i];
|
||||
unsigned opc = op->opcode[isa->hw_class];
|
||||
if ((op->flags & FF_GDS) || ((opc & 0xFF) != opc))
|
||||
continue; /* ignore GDS ops and INST_MOD versions for now */
|
||||
isa->fetch_map[opc] = i + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < TABLE_SIZE(cf_op_table); ++i) {
|
||||
const struct cf_op_info *op = &cf_op_table[i];
|
||||
unsigned opc = op->opcode[isa->hw_class];
|
||||
if (opc == -1)
|
||||
continue;
|
||||
/* using offset for CF_ALU_xxx opcodes because they overlap with other
|
||||
* CF opcodes (they use different encoding in hw) */
|
||||
if (op->flags & CF_ALU)
|
||||
opc += 0x80;
|
||||
isa->cf_map[opc] = i + 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r600_isa_destroy(struct r600_isa *isa) {
|
||||
|
||||
if (!isa)
|
||||
return 0;
|
||||
|
||||
if (isa->alu_op2_map)
|
||||
free(isa->alu_op2_map);
|
||||
if (isa->alu_op3_map)
|
||||
free(isa->alu_op3_map);
|
||||
if (isa->fetch_map)
|
||||
free(isa->fetch_map);
|
||||
if (isa->cf_map)
|
||||
free(isa->cf_map);
|
||||
|
||||
free(isa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
1223
src/gallium/drivers/r600/r600_isa.h
Normal file
1223
src/gallium/drivers/r600/r600_isa.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
#include "r600_pipe.h"
|
||||
#include "r600_public.h"
|
||||
#include "r600_isa.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
|
@ -260,6 +261,8 @@ static void r600_destroy_context(struct pipe_context *context)
|
|||
{
|
||||
struct r600_context *rctx = (struct r600_context *)context;
|
||||
|
||||
r600_isa_destroy(rctx->isa);
|
||||
|
||||
pipe_resource_reference((struct pipe_resource**)&rctx->dummy_cmask, NULL);
|
||||
pipe_resource_reference((struct pipe_resource**)&rctx->dummy_fmask, NULL);
|
||||
|
||||
|
|
@ -419,7 +422,11 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
|
|||
|
||||
rctx->allocator_so_filled_size = u_suballocator_create(&rctx->context, 4096, 4,
|
||||
0, PIPE_USAGE_STATIC, TRUE);
|
||||
if (!rctx->allocator_so_filled_size)
|
||||
if (!rctx->allocator_so_filled_size)
|
||||
goto fail;
|
||||
|
||||
rctx->isa = calloc(1, sizeof(struct r600_isa));
|
||||
if (!rctx->isa || r600_isa_init(rctx, rctx->isa))
|
||||
goto fail;
|
||||
|
||||
rctx->blitter = util_blitter_create(&rctx->context);
|
||||
|
|
|
|||
|
|
@ -552,6 +552,8 @@ struct r600_context {
|
|||
struct list_head dirty;
|
||||
struct list_head enable_list;
|
||||
unsigned pm4_dirty_cdwords;
|
||||
|
||||
struct r600_isa *isa;
|
||||
};
|
||||
|
||||
static INLINE void r600_emit_command_buffer(struct radeon_winsys_cs *cs,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -27,7 +27,7 @@ void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_c
|
|||
{
|
||||
unsigned count = (cf->ndw / 4) - 1;
|
||||
*bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
|
||||
*bytecode++ = cf->inst |
|
||||
*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_COUNT(count) |
|
||||
S_SQ_CF_WORD1_COUNT_3(count >> 3);
|
||||
|
|
@ -56,7 +56,7 @@ int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *
|
|||
S_SQ_ALU_WORD1_OP3_SRC2_REL(alu->src[2].rel) |
|
||||
S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
|
||||
S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
|
||||
S_SQ_ALU_WORD1_OP3_ALU_INST(alu->inst) |
|
||||
S_SQ_ALU_WORD1_OP3_ALU_INST(r600_isa_alu_opcode(bc->isa->hw_class, alu->op)) |
|
||||
S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle);
|
||||
} else {
|
||||
bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
|
||||
|
|
@ -67,7 +67,7 @@ int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *
|
|||
S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
|
||||
S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) |
|
||||
S_SQ_ALU_WORD1_OP2_OMOD(alu->omod) |
|
||||
S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) |
|
||||
S_SQ_ALU_WORD1_OP2_ALU_INST(r600_isa_alu_opcode(bc->isa->hw_class, alu->op)) |
|
||||
S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle) |
|
||||
S_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(alu->execute_mask) |
|
||||
S_SQ_ALU_WORD1_OP2_UPDATE_PRED(alu->update_pred);
|
||||
|
|
@ -75,7 +75,8 @@ int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *
|
|||
return 0;
|
||||
}
|
||||
|
||||
void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)
|
||||
void r700_bytecode_alu_read(struct r600_bytecode *bc,
|
||||
struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)
|
||||
{
|
||||
/* WORD0 */
|
||||
alu->src[0].sel = G_SQ_ALU_WORD0_SRC0_SEL(word0);
|
||||
|
|
@ -105,13 +106,15 @@ void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint3
|
|||
alu->src[2].rel = G_SQ_ALU_WORD1_OP3_SRC2_REL(word1);
|
||||
alu->src[2].chan = G_SQ_ALU_WORD1_OP3_SRC2_CHAN(word1);
|
||||
alu->src[2].neg = G_SQ_ALU_WORD1_OP3_SRC2_NEG(word1);
|
||||
alu->inst = G_SQ_ALU_WORD1_OP3_ALU_INST(word1);
|
||||
alu->op = r600_isa_alu_by_opcode(bc->isa,
|
||||
G_SQ_ALU_WORD1_OP3_ALU_INST(word1), 1);
|
||||
}
|
||||
else /*ALU_DWORD1_OP2*/
|
||||
{
|
||||
alu->src[0].abs = G_SQ_ALU_WORD1_OP2_SRC0_ABS(word1);
|
||||
alu->src[1].abs = G_SQ_ALU_WORD1_OP2_SRC1_ABS(word1);
|
||||
alu->inst = G_SQ_ALU_WORD1_OP2_ALU_INST(word1);
|
||||
alu->op = r600_isa_alu_by_opcode(bc->isa,
|
||||
G_SQ_ALU_WORD1_OP2_ALU_INST(word1), 0);
|
||||
alu->omod = G_SQ_ALU_WORD1_OP2_OMOD(word1);
|
||||
alu->dst.write = G_SQ_ALU_WORD1_OP2_WRITE_MASK(word1);
|
||||
alu->update_pred = G_SQ_ALU_WORD1_OP2_UPDATE_PRED(word1);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue