r600g: add r600 compile mode to compiler.
authorDave Airlie <airlied@redhat.com>
Wed, 21 Jul 2010 05:39:23 +0000 (15:39 +1000)
committerJerome Glisse <jglisse@redhat.com>
Wed, 21 Jul 2010 21:05:37 +0000 (17:05 -0400)
some of the ALU instructions are different on r6xx vs r7xx,
separate the alu translation to separate files, and use family
to pick which compile stage to use.

src/gallium/drivers/r600/r600_compiler_r600.c
src/gallium/drivers/r600/r600_compiler_r700.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_shader.h

index f7234e76469e5d08f109eceb9fb64077616950e7..27ad8f1a182a5e24e0b1a847d1d8b468e19e2050 100644 (file)
@@ -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;
+}
index ca6447e553c96d97cea9dcb171e4a657dc1074ac..0b43942866259052d47b61a9647bfad0c0151e2c 100644 (file)
@@ -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) {
index 2b1d54ad03af0b9122457c80552fbd30093ce895..f7d6e106638659eac84e9ef3d1afad9cb34a30ad 100644 (file)
@@ -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);
index 6e1bd1e37e5fe2d8ff0c065b5478c3af9d513096..40064ba8a997d755f509306c11e8fe57df8a01e5 100644 (file)
@@ -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,