diff options
-rw-r--r-- | src/gallium/drivers/r600/r600_compiler_r600.c | 65 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_compiler_r700.c | 43 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.h | 5 |
4 files changed, 106 insertions, 13 deletions
diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c index f7234e76469..27ad8f1a182 100644 --- a/src/gallium/drivers/r600/r600_compiler_r600.c +++ b/src/gallium/drivers/r600/r600_compiler_r600.c @@ -905,3 +905,68 @@ struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST] = { {C_OPCODE_ENTRY, INST_NOP}, {C_OPCODE_ARL, INST_NOP}, }; + + +static int r600_shader_alu_bytecode(struct r600_shader *rshader, + struct r600_shader_node *rnode, + struct r600_shader_inst *alu, + unsigned *cid) +{ + unsigned id = *cid; + + /* don't replace gpr by pv or ps for destination register */ + if (alu->is_op3) { + rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | + S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | + S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | + S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | + S_SQ_ALU_WORD0_LAST(alu->last); + rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | + S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | + S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) | + 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->opcode) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } else { + rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | + S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | + S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) | + S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | + S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | + S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) | + S_SQ_ALU_WORD0_LAST(alu->last); + rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | + S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | + S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) | + S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) | + S_SQ_ALU_WORD1_OP2_WRITE_MASK(1) | + S_SQ_ALU_WORD1_OP2_ALU_INST(alu->opcode) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } + *cid = id; + return 0; +} + +int r6xx_shader_alu_translate(struct r600_shader *rshader, + struct r600_shader_node *rnode, + unsigned *cid) +{ + struct r600_shader_alu *alu; + unsigned id = *cid; + int i; + int r = 0; + LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) { + for (i = 0; i < alu->nalu; i++) { + r = r600_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id); + if (r) + goto out; + } + for (i = 0; i < alu->nliteral; i++) { + rshader->bcode[id++] = alu->literal[i]; + } + } +out: + *cid = id; + return r; +} diff --git a/src/gallium/drivers/r600/r600_compiler_r700.c b/src/gallium/drivers/r600/r600_compiler_r700.c index ca6447e553c..0b439428662 100644 --- a/src/gallium/drivers/r600/r600_compiler_r700.c +++ b/src/gallium/drivers/r600/r600_compiler_r700.c @@ -143,14 +143,37 @@ static int r700_shader_alu_bytecode(struct r600_shader *rshader, return 0; } +static int r700_shader_alu_translate(struct r600_shader *rshader, + struct r600_shader_node *rnode, + unsigned *cid) + +{ + struct r600_shader_alu *alu; + unsigned id = *cid; + int i; + int r = 0; + LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) { + for (i = 0; i < alu->nalu; i++) { + r = r700_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id); + if (r) + goto out; + } + for (i = 0; i < alu->nliteral; i++) { + rshader->bcode[id++] = alu->literal[i]; + } + } + out: + *cid = id; + return r; +} + int r700_shader_translate(struct r600_shader *rshader) { struct c_shader *shader = &rshader->cshader; struct r600_shader_node *rnode; struct r600_shader_vfetch *vfetch; - struct r600_shader_alu *alu; struct c_vector *v; - unsigned id, i, end; + unsigned id, end; int r; r = r600_shader_register(rshader); @@ -179,16 +202,12 @@ int r700_shader_translate(struct r600_shader *rshader) if (r) return r; } - LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) { - for (i = 0; i < alu->nalu; i++) { - r = r700_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id); - if (r) - return r; - } - for (i = 0; i < alu->nliteral; i++) { - rshader->bcode[id++] = alu->literal[i]; - } - } + if (rshader->r6xx_compile) + r = r6xx_shader_alu_translate(rshader, rnode, &id); + else + r = r700_shader_alu_translate(rshader, rnode, &id); + if (r) + return r; } id = 0; LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) { diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 2b1d54ad03a..f7d6e106638 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -126,15 +126,19 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens) { + struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader); struct r600_shader *rshader = &rpshader->shader; int r; + enum radeon_family family; if (rpshader == NULL) return NULL; rpshader->type = type; + family = radeon_get_family(rscreen->rw); + rshader->r6xx_compile = (family >= CHIP_R600 && family < CHIP_RV770); LIST_INITHEAD(&rshader->nodes); - fprintf(stderr, "<<\n"); + fprintf(stderr, "<< %s\n", rshader->r6xx_compile ? "R600" : "R700"); tgsi_dump(tokens, 0); fprintf(stderr, "--------------------------------------------------------------\n"); r = c_shader_from_tgsi(&rshader->cshader, type, tokens); diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index 6e1bd1e37e5..40064ba8a99 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -96,6 +96,7 @@ struct r600_shader { u32 *bcode; /**< bytes code */ enum pipe_format resource_format[160]; /**< format of resource */ struct c_shader cshader; + boolean r6xx_compile; }; void r600_shader_cleanup(struct r600_shader *rshader); @@ -122,6 +123,10 @@ int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node); int r700_shader_translate(struct r600_shader *rshader); int r600_shader_insert_fetch(struct c_shader *shader); +int r6xx_shader_alu_translate(struct r600_shader *rshader, + struct r600_shader_node *rnode, + unsigned *cid); + enum r600_instruction { INST_ADD = 0, INST_MUL = 1, |