summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r600/r600_compiler_r600.c65
-rw-r--r--src/gallium/drivers/r600/r600_compiler_r700.c43
-rw-r--r--src/gallium/drivers/r600/r600_shader.c6
-rw-r--r--src/gallium/drivers/r600/r600_shader.h5
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,