r600: add support for GDS clause to the assembler.
This just adds enough for the tessellation shaders, which require TF_WRITE to work. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -193,3 +193,26 @@ int egcm_load_index_reg(struct r600_bytecode *bc, unsigned id, bool inside_alu_c
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eg_bytecode_gds_build(struct r600_bytecode *bc, struct r600_bytecode_gds *gds, unsigned id)
|
||||
{
|
||||
unsigned opcode = r600_isa_fetch_opcode(bc->isa->hw_class, gds->op) >> 8;
|
||||
bc->bytecode[id++] = S_SQ_MEM_GDS_WORD0_MEM_INST(2) |
|
||||
S_SQ_MEM_GDS_WORD0_MEM_OP(opcode) |
|
||||
S_SQ_MEM_GDS_WORD0_SRC_GPR(gds->src_gpr) |
|
||||
S_SQ_MEM_GDS_WORD0_SRC_REL(gds->src_rel) |
|
||||
S_SQ_MEM_GDS_WORD0_SRC_SEL_X(gds->src_sel_x) |
|
||||
S_SQ_MEM_GDS_WORD0_SRC_SEL_Y(gds->src_sel_y) |
|
||||
S_SQ_MEM_GDS_WORD0_SRC_SEL_Z(gds->src_sel_z);
|
||||
|
||||
bc->bytecode[id++] = S_SQ_MEM_GDS_WORD1_DST_GPR(gds->dst_gpr) |
|
||||
S_SQ_MEM_GDS_WORD1_DST_REL(gds->dst_rel) |
|
||||
S_SQ_MEM_GDS_WORD1_GDS_OP(gds->gds_op) |
|
||||
S_SQ_MEM_GDS_WORD1_SRC_GPR(gds->src_gpr2);
|
||||
|
||||
bc->bytecode[id++] = S_SQ_MEM_GDS_WORD2_DST_SEL_X(gds->dst_sel_x) |
|
||||
S_SQ_MEM_GDS_WORD2_DST_SEL_Y(gds->dst_sel_y) |
|
||||
S_SQ_MEM_GDS_WORD2_DST_SEL_Z(gds->dst_sel_z) |
|
||||
S_SQ_MEM_GDS_WORD2_DST_SEL_W(gds->dst_sel_w);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -514,6 +514,27 @@
|
||||
#define G_SQ_TEX_WORD2_SRC_SEL_W(x) (((x) >> 29) & 0x7)
|
||||
#define C_SQ_TEX_WORD2_SRC_SEL_W 0x1FFFFFFF
|
||||
|
||||
#define P_SQ_MEM_GDS_WORD0
|
||||
#define S_SQ_MEM_GDS_WORD0_MEM_INST(x) (((x) & 0x1f) << 0)
|
||||
#define S_SQ_MEM_GDS_WORD0_MEM_OP(x) (((x) & 0x7) << 8)
|
||||
#define S_SQ_MEM_GDS_WORD0_SRC_GPR(x) (((x) & 0x7f) << 11)
|
||||
#define S_SQ_MEM_GDS_WORD0_SRC_REL(x) (((x) & 0x3) << 18)
|
||||
#define S_SQ_MEM_GDS_WORD0_SRC_SEL_X(x) (((x) & 0x7) << 20)
|
||||
#define S_SQ_MEM_GDS_WORD0_SRC_SEL_Y(x) (((x) & 0x7) << 23)
|
||||
#define S_SQ_MEM_GDS_WORD0_SRC_SEL_Z(x) (((x) & 0x7) << 26)
|
||||
|
||||
#define P_SQ_MEM_GDS_WORD1
|
||||
#define S_SQ_MEM_GDS_WORD1_DST_GPR(x) (((x) & 0x7f) << 0)
|
||||
#define S_SQ_MEM_GDS_WORD1_DST_REL(x) (((x) & 0x3) << 7)
|
||||
#define S_SQ_MEM_GDS_WORD1_GDS_OP(x) (((x) & 0x3f) << 9)
|
||||
#define S_SQ_MEM_GDS_WORD1_SRC_GPR(x) (((x) & 0x7f) << 16)
|
||||
|
||||
#define P_SQ_MEM_GDS_WORD2
|
||||
#define S_SQ_MEM_GDS_WORD2_DST_SEL_X(x) (((x) & 0x7) << 0)
|
||||
#define S_SQ_MEM_GDS_WORD2_DST_SEL_Y(x) (((x) & 0x7) << 3)
|
||||
#define S_SQ_MEM_GDS_WORD2_DST_SEL_Z(x) (((x) & 0x7) << 6)
|
||||
#define S_SQ_MEM_GDS_WORD2_DST_SEL_W(x) (((x) & 0x7) << 9)
|
||||
|
||||
#define V_SQ_CF_COND_ACTIVE 0x00
|
||||
#define V_SQ_CF_COND_FALSE 0x01
|
||||
#define V_SQ_CF_COND_BOOL 0x02
|
||||
|
@@ -61,6 +61,7 @@ static struct r600_bytecode_cf *r600_bytecode_cf(void)
|
||||
LIST_INITHEAD(&cf->alu);
|
||||
LIST_INITHEAD(&cf->vtx);
|
||||
LIST_INITHEAD(&cf->tex);
|
||||
LIST_INITHEAD(&cf->gds);
|
||||
return cf;
|
||||
}
|
||||
|
||||
@@ -94,6 +95,16 @@ static struct r600_bytecode_tex *r600_bytecode_tex(void)
|
||||
return tex;
|
||||
}
|
||||
|
||||
static struct r600_bytecode_gds *r600_bytecode_gds(void)
|
||||
{
|
||||
struct r600_bytecode_gds *gds = CALLOC_STRUCT(r600_bytecode_gds);
|
||||
|
||||
if (gds == NULL)
|
||||
return NULL;
|
||||
LIST_INITHEAD(&gds->list);
|
||||
return gds;
|
||||
}
|
||||
|
||||
static unsigned stack_entry_size(enum radeon_family chip) {
|
||||
/* Wavefront size:
|
||||
* 64: R600/RV670/RV770/Cypress/R740/Barts/Turks/Caicos/
|
||||
@@ -1412,6 +1423,33 @@ int r600_bytecode_add_tex(struct r600_bytecode *bc, const struct r600_bytecode_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r600_bytecode_add_gds(struct r600_bytecode *bc, const struct r600_bytecode_gds *gds)
|
||||
{
|
||||
struct r600_bytecode_gds *ngds = r600_bytecode_gds();
|
||||
int r;
|
||||
|
||||
if (ngds == NULL)
|
||||
return -ENOMEM;
|
||||
memcpy(ngds, gds, sizeof(struct r600_bytecode_gds));
|
||||
|
||||
if (bc->cf_last == NULL ||
|
||||
bc->cf_last->op != CF_OP_GDS ||
|
||||
bc->force_add_cf) {
|
||||
r = r600_bytecode_add_cf(bc);
|
||||
if (r) {
|
||||
free(ngds);
|
||||
return r;
|
||||
}
|
||||
bc->cf_last->op = CF_OP_GDS;
|
||||
}
|
||||
|
||||
LIST_ADDTAIL(&ngds->list, &bc->cf_last->gds);
|
||||
bc->cf_last->ndw += 4; /* each GDS uses 4 dwords */
|
||||
if ((bc->cf_last->ndw / 4) >= r600_bytecode_num_tex_and_vtx_instructions(bc))
|
||||
bc->force_add_cf = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r600_bytecode_add_cfinst(struct r600_bytecode *bc, unsigned op)
|
||||
{
|
||||
int r;
|
||||
@@ -1623,6 +1661,7 @@ int r600_bytecode_build(struct r600_bytecode *bc)
|
||||
struct r600_bytecode_alu *alu;
|
||||
struct r600_bytecode_vtx *vtx;
|
||||
struct r600_bytecode_tex *tex;
|
||||
struct r600_bytecode_gds *gds;
|
||||
uint32_t literal[4];
|
||||
unsigned nliteral;
|
||||
unsigned addr;
|
||||
@@ -1701,6 +1740,14 @@ int r600_bytecode_build(struct r600_bytecode *bc)
|
||||
return r;
|
||||
addr += 4;
|
||||
}
|
||||
} else if (cf->op == CF_OP_GDS) {
|
||||
assert(bc->chip_class >= EVERGREEN);
|
||||
LIST_FOR_EACH_ENTRY(gds, &cf->gds, list) {
|
||||
r = eg_bytecode_gds_build(bc, gds, addr);
|
||||
if (r)
|
||||
return r;
|
||||
addr += 4;
|
||||
}
|
||||
} else if (cf->op == CF_OP_TEX) {
|
||||
LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
|
||||
assert(bc->chip_class >= EVERGREEN);
|
||||
@@ -1731,6 +1778,7 @@ void r600_bytecode_clear(struct r600_bytecode *bc)
|
||||
struct r600_bytecode_alu *alu = NULL, *next_alu;
|
||||
struct r600_bytecode_tex *tex = NULL, *next_tex;
|
||||
struct r600_bytecode_tex *vtx = NULL, *next_vtx;
|
||||
struct r600_bytecode_gds *gds = NULL, *next_gds;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(alu, next_alu, &cf->alu, list) {
|
||||
free(alu);
|
||||
@@ -1750,6 +1798,12 @@ void r600_bytecode_clear(struct r600_bytecode *bc)
|
||||
|
||||
LIST_INITHEAD(&cf->vtx);
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(gds, next_gds, &cf->gds, list) {
|
||||
free(gds);
|
||||
}
|
||||
|
||||
LIST_INITHEAD(&cf->gds);
|
||||
|
||||
free(cf);
|
||||
}
|
||||
|
||||
@@ -1911,6 +1965,7 @@ void r600_bytecode_disasm(struct r600_bytecode *bc)
|
||||
struct r600_bytecode_alu *alu = NULL;
|
||||
struct r600_bytecode_vtx *vtx = NULL;
|
||||
struct r600_bytecode_tex *tex = NULL;
|
||||
struct r600_bytecode_gds *gds = NULL;
|
||||
|
||||
unsigned i, id, ngr = 0, last;
|
||||
uint32_t literal[4];
|
||||
@@ -2194,6 +2249,33 @@ void r600_bytecode_disasm(struct r600_bytecode *bc)
|
||||
|
||||
id += 4;
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(gds, &cf->gds, list) {
|
||||
int o = 0;
|
||||
o += fprintf(stderr, " %04d %08X %08X %08X ", id, bc->bytecode[id],
|
||||
bc->bytecode[id + 1], bc->bytecode[id + 2]);
|
||||
|
||||
o += fprintf(stderr, "%s ", r600_isa_fetch(gds->op)->name);
|
||||
|
||||
if (gds->op != FETCH_OP_TF_WRITE) {
|
||||
o += fprintf(stderr, "R%d.", gds->dst_gpr);
|
||||
o += print_swizzle(gds->dst_sel_x);
|
||||
o += print_swizzle(gds->dst_sel_y);
|
||||
o += print_swizzle(gds->dst_sel_z);
|
||||
o += print_swizzle(gds->dst_sel_w);
|
||||
}
|
||||
|
||||
o += fprintf(stderr, ", R%d.", gds->src_gpr);
|
||||
o += print_swizzle(gds->src_sel_x);
|
||||
o += print_swizzle(gds->src_sel_y);
|
||||
o += print_swizzle(gds->src_sel_z);
|
||||
|
||||
if (gds->op != FETCH_OP_TF_WRITE) {
|
||||
o += fprintf(stderr, ", R%d.", gds->src_gpr2);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
id += 4;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "--------------------------------------\n");
|
||||
|
@@ -115,6 +115,24 @@ struct r600_bytecode_vtx {
|
||||
unsigned buffer_index_mode;
|
||||
};
|
||||
|
||||
struct r600_bytecode_gds {
|
||||
struct list_head list;
|
||||
unsigned op;
|
||||
unsigned gds_op;
|
||||
unsigned src_gpr;
|
||||
unsigned src_rel;
|
||||
unsigned src_sel_x;
|
||||
unsigned src_sel_y;
|
||||
unsigned src_sel_z;
|
||||
unsigned src_gpr2;
|
||||
unsigned dst_gpr;
|
||||
unsigned dst_rel;
|
||||
unsigned dst_sel_x;
|
||||
unsigned dst_sel_y;
|
||||
unsigned dst_sel_z;
|
||||
unsigned dst_sel_w;
|
||||
};
|
||||
|
||||
struct r600_bytecode_output {
|
||||
unsigned array_base;
|
||||
unsigned array_size;
|
||||
@@ -159,6 +177,7 @@ struct r600_bytecode_cf {
|
||||
struct list_head alu;
|
||||
struct list_head tex;
|
||||
struct list_head vtx;
|
||||
struct list_head gds;
|
||||
struct r600_bytecode_output output;
|
||||
struct r600_bytecode_alu *curr_bs_head;
|
||||
struct r600_bytecode_alu *prev_bs_head;
|
||||
@@ -233,7 +252,7 @@ struct r600_bytecode {
|
||||
/* eg_asm.c */
|
||||
int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf);
|
||||
int egcm_load_index_reg(struct r600_bytecode *bc, unsigned id, bool inside_alu_clause);
|
||||
|
||||
int eg_bytecode_gds_build(struct r600_bytecode *bc, struct r600_bytecode_gds *gds, unsigned id);
|
||||
/* r600_asm.c */
|
||||
void r600_bytecode_init(struct r600_bytecode *bc,
|
||||
enum chip_class chip_class,
|
||||
@@ -246,6 +265,8 @@ 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_gds(struct r600_bytecode *bc,
|
||||
const struct r600_bytecode_gds *gds);
|
||||
int r600_bytecode_add_output(struct r600_bytecode *bc,
|
||||
const struct r600_bytecode_output *output);
|
||||
int r600_bytecode_build(struct r600_bytecode *bc);
|
||||
|
Reference in New Issue
Block a user