summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2010-07-21 15:39:23 +1000
committerJerome Glisse <[email protected]>2010-07-21 17:05:37 -0400
commit4b2820534e3635a8ecd047f1e0139834e0a67d02 (patch)
tree986d5d76ad01b3aab78fe66af06d65d19e736d52 /src/gallium/drivers/r600
parent9433d0e8010bfe182762f8d2bd856a416a7f93bb (diff)
r600g: add r600 compile mode to compiler.
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.
Diffstat (limited to 'src/gallium/drivers/r600')
-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,