From 8556b77c56f3f1f0e75ce46d6b5c0d84c7b4eabd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 2 Jul 2010 15:27:17 +1000 Subject: r600: use gallium list macros instead of making our own. before this change, r600 glxinfo segfaulted in the list code, and I wasn't debugging another linked list implementation, its 2010 after all. So add the two missing list macros to the gallium header from X.org list header file (after fixing them), then port all r600 lists to the new header. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_compiler_r600.c | 58 +++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'src/gallium/drivers/r600/r600_compiler_r600.c') diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c index 14ea8ab6e8..fba0f3df42 100644 --- a/src/gallium/drivers/r600/r600_compiler_r600.c +++ b/src/gallium/drivers/r600/r600_compiler_r600.c @@ -53,7 +53,7 @@ int r600_shader_insert_fetch(struct c_shader *shader) vi = c_shader_vector_new(shader, C_FILE_INPUT, C_SEMANTIC_VERTEXID, -1); if (vi == NULL) return -ENOMEM; - c_list_for_each_safe(v, nv, &shader->files[C_FILE_INPUT].vectors) { + LIST_FOR_EACH_ENTRY_SAFE(v, nv, &shader->files[C_FILE_INPUT].vectors, head) { if (v == vi) continue; vr = c_shader_vector_new(shader, C_FILE_RESOURCE, C_SEMANTIC_GENERIC, -1); @@ -88,9 +88,9 @@ int r600_shader_insert_fetch(struct c_shader *shader) r = c_node_add_new_instruction_head(&shader->entry, &instruction); if (r) return r; - c_list_del(v); + LIST_DEL(&v->head); shader->files[C_FILE_INPUT].nvectors--; - c_list_add_tail(v, &shader->files[C_FILE_TEMPORARY].vectors); + LIST_ADDTAIL(&v->head, &shader->files[C_FILE_TEMPORARY].vectors); shader->files[C_FILE_TEMPORARY].nvectors++; v->file = C_FILE_TEMPORARY; } @@ -113,14 +113,14 @@ void r600_shader_cleanup(struct r600_shader *rshader) free(rshader->gpr); rshader->gpr = NULL; } - c_list_for_each_safe(n, nn, &rshader->nodes) { - c_list_del(n); - c_list_for_each_safe(vf, nvf, &n->vfetch) { - c_list_del(vf); + LIST_FOR_EACH_ENTRY_SAFE(n, nn, &rshader->nodes, head) { + LIST_DEL(&n->head); + LIST_FOR_EACH_ENTRY_SAFE(vf, nvf, &n->vfetch, head) { + LIST_DEL(&vf->head); free(vf); } - c_list_for_each_safe(alu, nalu, &n->alu) { - c_list_del(alu); + LIST_FOR_EACH_ENTRY_SAFE(alu, nalu, &n->alu, head) { + LIST_DEL(&alu->head); free(alu); } free(n); @@ -161,8 +161,8 @@ int r600_shader_update(struct r600_shader *rshader, enum pipe_format *resource_f memcpy(rshader->resource_format, resource_format, rshader->nresource * sizeof(enum pipe_format)); - c_list_for_each(rnode, &rshader->nodes) { - c_list_for_each(vfetch, &rnode->vfetch) { + LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) { + LIST_FOR_EACH_ENTRY(vfetch, &rnode->vfetch, head) { const struct util_format_description *desc; i = vfetch->cf_addr + 1; rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_X; @@ -197,7 +197,7 @@ int r600_shader_register(struct r600_shader *rshader) cid = 0; rid = 0; /* alloc input first */ - c_list_for_each(v, &rshader->cshader.files[C_FILE_INPUT].vectors) { + LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_INPUT].vectors, head) { nv = c_vector_new(); if (nv == NULL) { return -ENOMEM; @@ -209,7 +209,7 @@ int r600_shader_register(struct r600_shader *rshader) for (i = 0; i < C_FILE_COUNT; i++) { if (i == C_FILE_INPUT || i == C_FILE_IMMEDIATE) continue; - c_list_for_each(v, &rshader->cshader.files[i].vectors) { + LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[i].vectors, head) { switch (v->file) { case C_FILE_OUTPUT: case C_FILE_TEMPORARY: @@ -315,9 +315,9 @@ static struct r600_shader_node *r600_shader_new_node(struct r600_shader *rshader if (rnode == NULL) return NULL; rnode->node = node; - c_list_init(&rnode->vfetch); - c_list_init(&rnode->alu); - c_list_add_tail(rnode, &rshader->nodes); + LIST_INITHEAD(&rnode->vfetch); + LIST_INITHEAD(&rnode->alu); + LIST_ADDTAIL(&rnode->head, &rshader->nodes); return rnode; } @@ -333,7 +333,7 @@ static int r600_shader_add_vfetch(struct r600_shader *rshader, return 0; if (instruction->op[0].opcode != C_OPCODE_VFETCH) return 0; - if (!c_list_empty(&node->alu)) { + if (!LIST_IS_EMPTY(&node->alu)) { rnode = r600_shader_new_node(rshader, node->node); if (rnode == NULL) return -ENOMEM; @@ -355,7 +355,7 @@ static int r600_shader_add_vfetch(struct r600_shader *rshader, vfetch->dst[1].chan = C_SWIZZLE_Y; vfetch->dst[2].chan = C_SWIZZLE_Z; vfetch->dst[3].chan = C_SWIZZLE_W; - c_list_add_tail(vfetch, &node->vfetch); + LIST_ADDTAIL(&vfetch->head, &node->vfetch); node->nslot += 2; return 0; } @@ -369,7 +369,7 @@ static int r600_node_translate(struct r600_shader *rshader, struct c_node *node) rnode = r600_shader_new_node(rshader, node); if (rnode == NULL) return -ENOMEM; - c_list_for_each(instruction, &node->insts) { + LIST_FOR_EACH_ENTRY(instruction, &node->insts, head) { switch (instruction->op[0].opcode) { case C_OPCODE_VFETCH: r = r600_shader_add_vfetch(rshader, rnode, instruction); @@ -400,7 +400,7 @@ int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node) r = r600_node_translate(rshader, node); if (r) return r; - c_list_for_each(link, &node->childs) { + LIST_FOR_EACH_ENTRY(link, &node->childs, head) { r = r600_shader_translate_rec(rshader, link->node); if (r) return r; @@ -425,7 +425,7 @@ static struct r600_shader_alu *r600_shader_insert_alu(struct r600_shader *rshade alu->alu[2].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; alu->alu[3].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; alu->alu[4].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - c_list_add_tail(alu, &node->alu); + LIST_ADDTAIL(&alu->head, &node->alu); return alu; } @@ -437,7 +437,7 @@ static int r600_shader_alu_translate(struct r600_shader *rshader, struct r600_shader_alu *alu; int i, j, r, comp, litteral_lastcomp = -1; - if (!c_list_empty(&node->vfetch)) { + if (!LIST_IS_EMPTY(&node->vfetch)) { rnode = r600_shader_new_node(rshader, node->node); if (rnode == NULL) { fprintf(stderr, "%s %d new node failed\n", __func__, __LINE__); @@ -541,17 +541,17 @@ void r600_shader_node_place(struct r600_shader *rshader) rshader->ncf = 0; rshader->nslot = 0; - c_list_for_each_safe(node, nnode, &rshader->nodes) { - c_list_for_each_safe(alu, nalu, &node->alu) { + LIST_FOR_EACH_ENTRY_SAFE(node, nnode, &rshader->nodes, head) { + LIST_FOR_EACH_ENTRY_SAFE(alu, nalu, &node->alu, head) { node->nslot += alu->nalu; node->nslot += alu->nliteral >> 1; } node->nfetch = 0; - c_list_for_each_safe(vfetch, nvfetch, &node->vfetch) { + LIST_FOR_EACH_ENTRY_SAFE(vfetch, nvfetch, &node->vfetch, head) { node->nslot += 2; node->nfetch += 1; } - if (!c_list_empty(&node->vfetch)) { + if (!LIST_IS_EMPTY(&node->vfetch)) { /* fetch node need to be 16 bytes aligned*/ cf_addr += 1; cf_addr &= 0xFFFFFFFEUL; @@ -563,7 +563,7 @@ void r600_shader_node_place(struct r600_shader *rshader) rshader->ncf++; } rshader->nslot = cf_addr; - c_list_for_each_safe(node, nnode, &rshader->nodes) { + LIST_FOR_EACH_ENTRY_SAFE(node, nnode, &rshader->nodes, head) { node->cf_addr += cf_id * 2; } rshader->ncf += rshader->cshader.files[C_FILE_OUTPUT].nvectors; @@ -584,7 +584,7 @@ static int r600_cshader_legalize_rec(struct c_shader *shader, struct c_node *nod unsigned k; int r; - c_list_for_each(i, &node->insts) { + LIST_FOR_EACH_ENTRY(i, &node->insts, head) { for (k = 0; k < i->nop; k++) { switch (i->op[k].opcode) { case C_OPCODE_SLT: @@ -598,7 +598,7 @@ static int r600_cshader_legalize_rec(struct c_shader *shader, struct c_node *nod } } } - c_list_for_each(link, &node->childs) { + LIST_FOR_EACH_ENTRY(link, &node->childs, head) { r = r600_cshader_legalize_rec(shader, link->node); if (r) { return r; -- cgit v1.2.3 From 62f8b56dc6bcc13a30ed4f8c2d71e5a139b57b33 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 20 Jul 2010 15:04:55 -0400 Subject: r600g: split trans unit computation Signed-off-by: Jerome Glisse --- src/gallium/drivers/r600/r600_compiler_r600.c | 28 +++++++++++++++++++++------ src/gallium/drivers/r600/r600_shader.c | 2 +- 2 files changed, 23 insertions(+), 7 deletions(-) (limited to 'src/gallium/drivers/r600/r600_compiler_r600.c') diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c index fba0f3df42..f7234e7646 100644 --- a/src/gallium/drivers/r600/r600_compiler_r600.c +++ b/src/gallium/drivers/r600/r600_compiler_r600.c @@ -316,6 +316,7 @@ static struct r600_shader_node *r600_shader_new_node(struct r600_shader *rshader return NULL; rnode->node = node; LIST_INITHEAD(&rnode->vfetch); +fprintf(stderr, "------------------------ new node (%p %p)\n", &rnode->vfetch, rnode->vfetch.next); LIST_INITHEAD(&rnode->alu); LIST_ADDTAIL(&rnode->head, &rshader->nodes); return rnode; @@ -425,6 +426,9 @@ static struct r600_shader_alu *r600_shader_insert_alu(struct r600_shader *rshade alu->alu[2].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; alu->alu[3].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; alu->alu[4].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu->alu[1].dst.chan = 1; + alu->alu[2].dst.chan = 2; + alu->alu[3].dst.chan = 3; LIST_ADDTAIL(&alu->head, &node->alu); return alu; } @@ -435,9 +439,10 @@ static int r600_shader_alu_translate(struct r600_shader *rshader, { struct r600_shader_node *rnode; struct r600_shader_alu *alu; - int i, j, r, comp, litteral_lastcomp = -1; + int i, j, r, litteral_lastcomp = -1; if (!LIST_IS_EMPTY(&node->vfetch)) { +fprintf(stderr, "------------------------ add node (%p %p)\n", &node->vfetch, node->vfetch.next); rnode = r600_shader_new_node(rshader, node->node); if (rnode == NULL) { fprintf(stderr, "%s %d new node failed\n", __func__, __LINE__); @@ -468,7 +473,7 @@ static int r600_shader_alu_translate(struct r600_shader *rshader, case C_SWIZZLE_0: case C_SWIZZLE_1: default: - fprintf(stderr, "%s %d invalid output\n", __func__, __LINE__); + fprintf(stderr, "%s %d invalid output %d\n", __func__, __LINE__, comp); return -EINVAL; } alu->alu[comp].inst = ainfo->instruction; @@ -521,8 +526,7 @@ static int r600_shader_alu_translate(struct r600_shader *rshader, default: break; } -printf("nliteral: %d\n", alu->nliteral); - for (i = instruction->nop; i >= 0; i--) { + for (i = 4; i >= 0; i--) { if (alu->alu[i].inst != INST_NOP) { alu->alu[i].last = 1; alu->nalu = i + 1; @@ -579,9 +583,9 @@ int r600_shader_legalize(struct r600_shader *rshader) static int r600_cshader_legalize_rec(struct c_shader *shader, struct c_node *node) { struct c_node_link *link; - struct c_instruction *i; + struct c_instruction *i, *n; struct c_operand operand; - unsigned k; + unsigned k, inst; int r; LIST_FOR_EACH_ENTRY(i, &node->insts, head) { @@ -596,6 +600,18 @@ static int r600_cshader_legalize_rec(struct c_shader *shader, struct c_node *nod default: break; } + inst = r600_alu_instruction[i->op[k].opcode].instruction; + if (r600_instruction_info[inst].is_trans && k < (i->nop -1)) { + /* split trans opcode */ + n = CALLOC_STRUCT(c_instruction); + if (n == NULL) + return -ENOMEM; + for (n->nop = 0, k = k + 1; k < i->nop; k++, n->nop++) { + memcpy(&n->op[n->nop - 0], &i->op[k], sizeof(struct c_op)); + } + i->nop -= n->nop; + LIST_ADD(&n->head, &i->head); + } } } LIST_FOR_EACH_ENTRY(link, &node->childs, head) { diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 2cbfde8713..2b1d54ad03 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -155,13 +155,13 @@ struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsig fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); return NULL; } - c_shader_dump(&rshader->cshader); r = r600_cshader_legalize(&rshader->cshader); if (r) { r600_pipe_shader_destroy(ctx, rpshader); fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); return NULL; } + c_shader_dump(&rshader->cshader); r = r700_shader_translate(rshader); if (r) { r600_pipe_shader_destroy(ctx, rpshader); -- cgit v1.2.3 From 4b2820534e3635a8ecd047f1e0139834e0a67d02 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 21 Jul 2010 15:39:23 +1000 Subject: 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. --- src/gallium/drivers/r600/r600_compiler_r600.c | 65 +++++++++++++++++++++++++++ src/gallium/drivers/r600/r600_compiler_r700.c | 43 +++++++++++++----- src/gallium/drivers/r600/r600_shader.c | 6 ++- src/gallium/drivers/r600/r600_shader.h | 5 +++ 4 files changed, 106 insertions(+), 13 deletions(-) (limited to 'src/gallium/drivers/r600/r600_compiler_r600.c') diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c index f7234e7646..27ad8f1a18 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 ca6447e553..0b43942866 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 2b1d54ad03..f7d6e10663 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 6e1bd1e37e..40064ba8a9 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, -- cgit v1.2.3 From de553d906b4a205d811a9e1651f14212ec284e29 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 23 Jul 2010 17:32:32 -0400 Subject: r600g: drop compiler stuff and switch over dumb tgsi assembler Writing a compiler is time consuming and error prone in order to allow r600g to further progress in the meantime i wrote a simple tgsi assembler, it does stupid thing but i would rather keep the code simple than having people trying to optimize code it does. Signed-off-by: Jerome Glisse --- src/gallium/drivers/r600/Makefile | 7 +- src/gallium/drivers/r600/r600_asm.c | 385 ++++++++++ src/gallium/drivers/r600/r600_asm.h | 112 +++ src/gallium/drivers/r600/r600_compiler.c | 447 ------------ src/gallium/drivers/r600/r600_compiler.h | 320 --------- src/gallium/drivers/r600/r600_compiler_dump.c | 267 ------- src/gallium/drivers/r600/r600_compiler_r600.c | 972 -------------------------- src/gallium/drivers/r600/r600_compiler_r700.c | 233 ------ src/gallium/drivers/r600/r600_compiler_tgsi.c | 730 ------------------- src/gallium/drivers/r600/r600_context.c | 2 +- src/gallium/drivers/r600/r600_context.h | 5 +- src/gallium/drivers/r600/r600_shader.c | 784 ++++++++++++++++++--- src/gallium/drivers/r600/r600_shader.h | 244 +------ src/gallium/drivers/r600/r600_sq.h | 18 +- src/gallium/drivers/r600/r600_state.c | 4 +- src/gallium/drivers/r600/r700_asm.c | 70 ++ 16 files changed, 1277 insertions(+), 3323 deletions(-) create mode 100644 src/gallium/drivers/r600/r600_asm.c create mode 100644 src/gallium/drivers/r600/r600_asm.h delete mode 100644 src/gallium/drivers/r600/r600_compiler.c delete mode 100644 src/gallium/drivers/r600/r600_compiler.h delete mode 100644 src/gallium/drivers/r600/r600_compiler_dump.c delete mode 100644 src/gallium/drivers/r600/r600_compiler_r600.c delete mode 100644 src/gallium/drivers/r600/r600_compiler_r700.c delete mode 100644 src/gallium/drivers/r600/r600_compiler_tgsi.c create mode 100644 src/gallium/drivers/r600/r700_asm.c (limited to 'src/gallium/drivers/r600/r600_compiler_r600.c') diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile index aae31a6a6e..8f1e1366b5 100644 --- a/src/gallium/drivers/r600/Makefile +++ b/src/gallium/drivers/r600/Makefile @@ -18,10 +18,7 @@ C_SOURCES = \ r600_state.c \ r600_texture.c \ r600_shader.c \ - r600_compiler.c \ - r600_compiler_tgsi.c \ - r600_compiler_dump.c \ - r600_compiler_r600.c \ - r600_compiler_r700.c + r600_asm.c \ + r700_asm.c include ../../Makefile.template diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c new file mode 100644 index 0000000000..6e48703a57 --- /dev/null +++ b/src/gallium/drivers/r600/r600_asm.c @@ -0,0 +1,385 @@ +/* + * Copyright 2010 Jerome Glisse + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "r600_asm.h" +#include "r600_context.h" +#include "util/u_memory.h" +#include "r600_sq.h" +#include +#include + +int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id); + +static struct r600_bc_cf *r600_bc_cf(void) +{ + struct r600_bc_cf *cf = CALLOC_STRUCT(r600_bc_cf); + + if (cf == NULL) + return NULL; + LIST_INITHEAD(&cf->list); + LIST_INITHEAD(&cf->alu); + LIST_INITHEAD(&cf->vtx); + return cf; +} + +static struct r600_bc_alu *r600_bc_alu(void) +{ + struct r600_bc_alu *alu = CALLOC_STRUCT(r600_bc_alu); + + if (alu == NULL) + return NULL; + LIST_INITHEAD(&alu->list); + return alu; +} + +static struct r600_bc_vtx *r600_bc_vtx(void) +{ + struct r600_bc_vtx *vtx = CALLOC_STRUCT(r600_bc_vtx); + + if (vtx == NULL) + return NULL; + LIST_INITHEAD(&vtx->list); + return vtx; +} + +int r600_bc_init(struct r600_bc *bc, enum radeon_family family) +{ + LIST_INITHEAD(&bc->cf); + bc->family = family; + return 0; +} + +static int r600_bc_add_cf(struct r600_bc *bc) +{ + struct r600_bc_cf *cf = r600_bc_cf(); + + if (cf == NULL) + return -ENOMEM; + LIST_ADDTAIL(&cf->list, &bc->cf); + if (bc->cf_last) + cf->id = bc->cf_last->id + 2; + bc->cf_last = cf; + bc->ncf++; + bc->ndw += 2; + return 0; +} + +int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output) +{ + int r; + + r = r600_bc_add_cf(bc); + if (r) + return r; + bc->cf_last->inst = output->inst; + memcpy(&bc->cf_last->output, output, sizeof(struct r600_bc_output)); + return 0; +} + +int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu) +{ + struct r600_bc_alu *nalu = r600_bc_alu(); + struct r600_bc_alu *lalu; + int i, r; + + if (nalu == NULL) + return -ENOMEM; + memcpy(nalu, alu, sizeof(struct r600_bc_alu)); + nalu->nliteral = 0; + + /* cf can contains only alu or only vtx or only tex */ + if (bc->cf_last == NULL || bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3)) { + r = r600_bc_add_cf(bc); + if (r) { + free(nalu); + return r; + } + bc->cf_last->inst = V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3; + } + /* number of gpr == the last gpr used in any alu */ + for (i = 0; i < 3; i++) { + if (alu->src[i].sel >= bc->ngpr && alu->src[i].sel < 128) { + bc->ngpr = alu->src[i].sel + 1; + } + /* compute how many literal are needed + * either 2 or 4 literals + */ + if (alu->src[i].sel == 253) { + if (((alu->src[i].chan + 2) & 0x6) > nalu->nliteral) { + nalu->nliteral = (alu->src[i].chan + 2) & 0x6; + } + } + } + if (!LIST_IS_EMPTY(&bc->cf_last->alu)) { + lalu = LIST_ENTRY(struct r600_bc_alu, bc->cf_last->alu.prev, list); + if (!lalu->last && lalu->nliteral > nalu->nliteral) { + nalu->nliteral = lalu->nliteral; + } + } + if (alu->dst.sel >= bc->ngpr) { + bc->ngpr = alu->dst.sel + 1; + } + LIST_ADDTAIL(&nalu->list, &bc->cf_last->alu); + /* each alu use 2 dwords */ + bc->cf_last->ndw += 2; + bc->ndw += 2; + return 0; +} + +int r600_bc_add_literal(struct r600_bc *bc, const u32 *value) +{ + struct r600_bc_alu *alu; + + if (bc->cf_last == NULL || + bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) || + LIST_IS_EMPTY(&bc->cf_last->alu)) { + R600_ERR("last CF is not ALU (%p)\n", bc->cf_last); + return -EINVAL; + } + alu = LIST_ENTRY(struct r600_bc_alu, bc->cf_last->alu.prev, list); + if (!alu->last || !alu->nliteral) { + return 0; + } + memcpy(alu->value, value, 4 * 4); + bc->cf_last->ndw += alu->nliteral; + bc->ndw += alu->nliteral; + return 0; +} + +int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx) +{ + struct r600_bc_vtx *nvtx = r600_bc_vtx(); + int r; + + if (nvtx == NULL) + return -ENOMEM; + memcpy(nvtx, vtx, sizeof(struct r600_bc_vtx)); + + /* cf can contains only alu or only vtx or only tex */ + if (bc->cf_last == NULL || + (bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX && + bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC)) { + r = r600_bc_add_cf(bc); + if (r) { + free(nvtx); + return r; + } + bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_VTX; + } + LIST_ADDTAIL(&nvtx->list, &bc->cf_last->vtx); + /* each fetch use 6 dwords */ + bc->cf_last->ndw += 4; + bc->ndw += 4; + return 0; +} + +int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id) +{ + bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) | + S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) | + S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x) | + S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(vtx->mega_fetch_count); + bc->bytecode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vtx->dst_sel_x) | + S_SQ_VTX_WORD1_DST_SEL_Y(vtx->dst_sel_y) | + S_SQ_VTX_WORD1_DST_SEL_Z(vtx->dst_sel_z) | + S_SQ_VTX_WORD1_DST_SEL_W(vtx->dst_sel_w) | + S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) | + S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr); + bc->bytecode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1); + bc->bytecode[id++] = 0; + return 0; +} + +int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id) +{ + unsigned i; + + /* don't replace gpr by pv or ps for destination register */ + if (alu->is_op3) { + bc->bytecode[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); + bc->bytecode[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->inst) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } else { + bc->bytecode[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); + bc->bytecode[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(alu->dst.write) | + S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } + if (alu->last) { + for (i = 0; i < alu->nliteral; i++) { + bc->bytecode[id++] = alu->value[i]; + } + } + return 0; +} + +int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) +{ + unsigned id = cf->id; + + switch (cf->inst) { + case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): + bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1); + bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) | + S_SQ_CF_ALU_WORD1_BARRIER(1) | + S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1); + break; + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1); + bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) | + S_SQ_CF_WORD1_BARRIER(1) | + S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1); + break; + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) | + S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) | + S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) | + S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type); + bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) | + S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) | + S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) | + S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) | + S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) | + S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst) | + S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program); + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; + } + return 0; +} + +int r600_bc_build(struct r600_bc *bc) +{ + struct r600_bc_cf *cf; + struct r600_bc_alu *alu; + struct r600_bc_vtx *vtx; + unsigned addr; + int r; + + + /* first path compute addr of each CF block */ + /* addr start after all the CF instructions */ + addr = bc->cf_last->id + 2; + LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { + switch (cf->inst) { + case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): + break; + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + /* fetch node need to be 16 bytes aligned*/ + addr += 3; + addr &= 0xFFFFFFFCUL; + break; + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; + } + cf->addr = addr; + addr += cf->ndw; + bc->ndw = cf->addr + cf->ndw; + } + free(bc->bytecode); + bc->bytecode = calloc(1, bc->ndw * 4); + if (bc->bytecode == NULL) + return -ENOMEM; + LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { + addr = cf->addr; + r = r600_bc_cf_build(bc, cf); + if (r) + return r; + switch (cf->inst) { + case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): + LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { + switch (bc->family) { + case CHIP_R600: + case CHIP_RV610: + case CHIP_RV630: + case CHIP_RV670: + case CHIP_RV620: + case CHIP_RV635: + case CHIP_RS780: + case CHIP_RS880: + r = r600_bc_alu_build(bc, alu, addr); + break; + case CHIP_RV770: + case CHIP_RV730: + case CHIP_RV710: + case CHIP_RV740: + r = r700_bc_alu_build(bc, alu, addr); + break; + default: + R600_ERR("unknown family %d\n", bc->family); + return -EINVAL; + } + if (r) + return r; + addr += 2; + if (alu->last) { + addr += alu->nliteral; + } + } + break; + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) { + r = r600_bc_vtx_build(bc, vtx, addr); + if (r) + return r; + addr += 4; + } + break; + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; + } + } + return 0; +} diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h new file mode 100644 index 0000000000..8a874a9df5 --- /dev/null +++ b/src/gallium/drivers/r600/r600_asm.h @@ -0,0 +1,112 @@ +/* + * Copyright 2010 Jerome Glisse + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef R600_ASM_H +#define R600_ASM_H + +#include "radeon.h" +#include "util/u_double_list.h" + +struct r600_bc_alu_src { + unsigned sel; + unsigned chan; + unsigned neg; + unsigned abs; +}; + +struct r600_bc_alu_dst { + unsigned sel; + unsigned chan; + unsigned clamp; + unsigned write; +}; + +struct r600_bc_alu { + struct list_head list; + struct r600_bc_alu_src src[3]; + struct r600_bc_alu_dst dst; + unsigned inst; + unsigned last; + unsigned is_op3; + unsigned nliteral; + u32 value[4]; +}; + +struct r600_bc_vtx { + struct list_head list; + unsigned inst; + unsigned fetch_type; + unsigned buffer_id; + unsigned src_gpr; + unsigned src_sel_x; + unsigned mega_fetch_count; + unsigned dst_gpr; + unsigned dst_sel_x; + unsigned dst_sel_y; + unsigned dst_sel_z; + unsigned dst_sel_w; +}; + +struct r600_bc_output { + unsigned array_base; + unsigned type; + unsigned end_of_program; + unsigned inst; + unsigned elem_size; + unsigned gpr; + unsigned swizzle_x; + unsigned swizzle_y; + unsigned swizzle_z; + unsigned swizzle_w; + unsigned barrier; +}; + +struct r600_bc_cf { + struct list_head list; + unsigned inst; + unsigned addr; + unsigned ndw; + unsigned id; + struct list_head alu; + struct list_head vtx; + struct r600_bc_output output; +}; + +struct r600_bc { + enum radeon_family family; + struct list_head cf; + struct r600_bc_cf *cf_last; + unsigned ndw; + unsigned ncf; + unsigned ngpr; + unsigned nresource; + u32 *bytecode; +}; + +int r600_bc_init(struct r600_bc *bc, enum radeon_family family); +int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu); +int r600_bc_add_literal(struct r600_bc *bc, const u32 *value); +int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx); +int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output); +int r600_bc_build(struct r600_bc *bc); + +#endif diff --git a/src/gallium/drivers/r600/r600_compiler.c b/src/gallium/drivers/r600/r600_compiler.c deleted file mode 100644 index 1804b86d24..0000000000 --- a/src/gallium/drivers/r600/r600_compiler.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include -#include -#include -#include "r600_compiler.h" - -struct c_vector *c_vector_new(void) -{ - struct c_vector *v = calloc(1, sizeof(struct c_vector)); - - if (v == NULL) { - return NULL; - } - LIST_INITHEAD(&v->head); - return v; -} - -static unsigned c_opcode_is_alu(unsigned opcode) -{ - switch (opcode) { - case C_OPCODE_MOV: - case C_OPCODE_MUL: - case C_OPCODE_MAD: - case C_OPCODE_ARL: - case C_OPCODE_LIT: - case C_OPCODE_RCP: - case C_OPCODE_RSQ: - case C_OPCODE_EXP: - case C_OPCODE_LOG: - case C_OPCODE_ADD: - case C_OPCODE_DP3: - case C_OPCODE_DP4: - case C_OPCODE_DST: - case C_OPCODE_MIN: - case C_OPCODE_MAX: - case C_OPCODE_SLT: - case C_OPCODE_SGE: - case C_OPCODE_SUB: - case C_OPCODE_LRP: - case C_OPCODE_CND: - case C_OPCODE_DP2A: - case C_OPCODE_FRC: - case C_OPCODE_CLAMP: - case C_OPCODE_FLR: - case C_OPCODE_ROUND: - case C_OPCODE_EX2: - case C_OPCODE_LG2: - case C_OPCODE_POW: - case C_OPCODE_XPD: - case C_OPCODE_ABS: - case C_OPCODE_RCC: - case C_OPCODE_DPH: - case C_OPCODE_COS: - case C_OPCODE_DDX: - case C_OPCODE_DDY: - case C_OPCODE_PK2H: - case C_OPCODE_PK2US: - case C_OPCODE_PK4B: - case C_OPCODE_PK4UB: - case C_OPCODE_RFL: - case C_OPCODE_SEQ: - case C_OPCODE_SFL: - case C_OPCODE_SGT: - case C_OPCODE_SIN: - case C_OPCODE_SLE: - case C_OPCODE_SNE: - case C_OPCODE_STR: - case C_OPCODE_UP2H: - case C_OPCODE_UP2US: - case C_OPCODE_UP4B: - case C_OPCODE_UP4UB: - case C_OPCODE_X2D: - case C_OPCODE_ARA: - case C_OPCODE_ARR: - case C_OPCODE_BRA: - case C_OPCODE_SSG: - case C_OPCODE_CMP: - case C_OPCODE_SCS: - case C_OPCODE_NRM: - case C_OPCODE_DIV: - case C_OPCODE_DP2: - case C_OPCODE_CEIL: - case C_OPCODE_I2F: - case C_OPCODE_NOT: - case C_OPCODE_TRUNC: - case C_OPCODE_SHL: - case C_OPCODE_AND: - case C_OPCODE_OR: - case C_OPCODE_MOD: - case C_OPCODE_XOR: - case C_OPCODE_SAD: - case C_OPCODE_NRM4: - case C_OPCODE_F2I: - case C_OPCODE_IDIV: - case C_OPCODE_IMAX: - case C_OPCODE_IMIN: - case C_OPCODE_INEG: - case C_OPCODE_ISGE: - case C_OPCODE_ISHR: - case C_OPCODE_ISLT: - case C_OPCODE_F2U: - case C_OPCODE_U2F: - case C_OPCODE_UADD: - case C_OPCODE_UDIV: - case C_OPCODE_UMAD: - case C_OPCODE_UMAX: - case C_OPCODE_UMIN: - case C_OPCODE_UMOD: - case C_OPCODE_UMUL: - case C_OPCODE_USEQ: - case C_OPCODE_USGE: - case C_OPCODE_USHR: - case C_OPCODE_USLT: - case C_OPCODE_USNE: - return 1; - case C_OPCODE_END: - case C_OPCODE_VFETCH: - case C_OPCODE_KILP: - case C_OPCODE_CAL: - case C_OPCODE_RET: - case C_OPCODE_TXB: - case C_OPCODE_TXL: - case C_OPCODE_BRK: - case C_OPCODE_IF: - case C_OPCODE_BGNFOR: - case C_OPCODE_REP: - case C_OPCODE_ELSE: - case C_OPCODE_ENDIF: - case C_OPCODE_ENDFOR: - case C_OPCODE_ENDREP: - case C_OPCODE_PUSHA: - case C_OPCODE_POPA: - case C_OPCODE_TXF: - case C_OPCODE_TXQ: - case C_OPCODE_CONT: - case C_OPCODE_EMIT: - case C_OPCODE_ENDPRIM: - case C_OPCODE_BGNLOOP: - case C_OPCODE_BGNSUB: - case C_OPCODE_ENDLOOP: - case C_OPCODE_ENDSUB: - case C_OPCODE_NOP: - case C_OPCODE_CALLNZ: - case C_OPCODE_IFC: - case C_OPCODE_BREAKC: - case C_OPCODE_KIL: - case C_OPCODE_TEX: - case C_OPCODE_TXD: - case C_OPCODE_TXP: - case C_OPCODE_SWITCH: - case C_OPCODE_CASE: - case C_OPCODE_DEFAULT: - case C_OPCODE_ENDSWITCH: - default: - return 0; - } -} - - -/* NEW */ -void c_node_init(struct c_node *node) -{ - memset(node, 0, sizeof(struct c_node)); - LIST_INITHEAD(&node->predecessors); - LIST_INITHEAD(&node->successors); - LIST_INITHEAD(&node->childs); - LIST_INITHEAD(&node->insts); - node->parent = NULL; -} - -static struct c_node_link *c_node_link_new(struct c_node *node) -{ - struct c_node_link *link; - - link = calloc(1, sizeof(struct c_node_link)); - if (link == NULL) - return NULL; - LIST_INITHEAD(&link->head); - link->node = node; - return link; -} - -int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor) -{ - struct c_node_link *pedge, *sedge; - - pedge = c_node_link_new(successor); - sedge = c_node_link_new(predecessor); - if (sedge == NULL || pedge == NULL) { - free(sedge); - free(pedge); - return -ENOMEM; - } - LIST_ADDTAIL(&pedge->head, &predecessor->successors); - LIST_ADDTAIL(&sedge->head, &successor->predecessors); - - return 0; -} - -int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction) -{ - struct c_instruction *inst = malloc(sizeof(struct c_instruction)); - - if (inst == NULL) - return -ENOMEM; - memcpy(inst, instruction, sizeof(struct c_instruction)); - LIST_ADD(&inst->head, &node->insts); - return 0; -} - -int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction) -{ - struct c_instruction *inst = malloc(sizeof(struct c_instruction)); - - if (inst == NULL) - return -ENOMEM; - memcpy(inst, instruction, sizeof(struct c_instruction)); - LIST_ADDTAIL(&inst->head, &node->insts); - return 0; -} - -struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor) -{ - struct c_node *node = calloc(1, sizeof(struct c_node)); - - if (node == NULL) - return NULL; - c_node_init(node); - if (c_node_cfg_link(predecessor, node)) { - free(node); - return NULL; - } - LIST_ADDTAIL(&node->head, &shader->nodes); - return node; -} - -int c_shader_init(struct c_shader *shader, unsigned type) -{ - unsigned i; - int r; - - shader->type = type; - for (i = 0; i < C_FILE_COUNT; i++) { - shader->files[i].nvectors = 0; - LIST_INITHEAD(&shader->files[i].vectors); - } - LIST_INITHEAD(&shader->nodes); - c_node_init(&shader->entry); - c_node_init(&shader->end); - shader->entry.opcode = C_OPCODE_ENTRY; - shader->end.opcode = C_OPCODE_END; - r = c_node_cfg_link(&shader->entry, &shader->end); - if (r) - return r; - return 0; -} - -struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid) -{ - struct c_vector *v = calloc(1, sizeof(struct c_vector)); - int i; - - if (v == NULL) { - return NULL; - } - for (i = 0; i < 4; i++) { - v->channel[i] = calloc(1, sizeof(struct c_channel)); - if (v->channel[i] == NULL) - goto out_err; - v->channel[i]->vindex = i; - v->channel[i]->vector = v; - } - v->file = file; - v->name = name; - v->sid = sid; - shader->files[v->file].nvectors++; - v->id = shader->nvectors++; - LIST_ADDTAIL(&v->head, &shader->files[v->file].vectors); - return v; -out_err: - for (i = 0; i < 4; i++) { - free(v->channel[i]); - } - free(v); - return NULL; -} - -static void c_node_remove_link(struct list_head *head, struct c_node *node) -{ - struct c_node_link *link, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(link, tmp, head, head) { - if (link->node == node) { - LIST_DEL(&link->head); - free(link); - } - } -} - -static void c_node_destroy(struct c_node *node) -{ - struct c_instruction *i, *ni; - struct c_node_link *link, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(i, ni, &node->insts, head) { - LIST_DEL(&i->head); - free(i); - } - if (node->parent) - c_node_remove_link(&node->parent->childs, node); - node->parent = NULL; - LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->predecessors, head) { - c_node_remove_link(&link->node->successors, node); - LIST_DEL(&link->head); - free(link); - } - LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->successors, head) { - c_node_remove_link(&link->node->predecessors, node); - LIST_DEL(&link->head); - free(link); - } - LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->childs, head) { - link->node->parent = NULL; - LIST_DEL(&link->head); - free(link); - } -} - -void c_shader_destroy(struct c_shader *shader) -{ - struct c_node *n, *nn; - struct c_vector *v, *nv; - unsigned i; - - for (i = 0; i < C_FILE_COUNT; i++) { - shader->files[i].nvectors = 0; - LIST_FOR_EACH_ENTRY_SAFE(v, nv, &shader->files[i].vectors, head) { - LIST_DEL(&v->head); - free(v->channel[0]); - free(v->channel[1]); - free(v->channel[2]); - free(v->channel[3]); - free(v); - } - } - LIST_FOR_EACH_ENTRY_SAFE(n, nn, &shader->nodes, head) { - LIST_DEL(&n->head); - c_node_destroy(n); - } - memset(shader, 0, sizeof(struct c_shader)); -} - -static void c_shader_dfs_without_rec(struct c_node *entry, struct c_node *node) -{ - struct c_node_link *link; - - if (entry == node || entry->visited) - return; - entry->visited = 1; - LIST_FOR_EACH_ENTRY(link, &entry->successors, head) { - c_shader_dfs_without_rec(link->node, node); - } -} - -static void c_shader_dfs_without(struct c_shader *shader, struct c_node *node) -{ - struct c_node *n; - - shader->entry.visited = 0; - shader->end.visited = 0; - LIST_FOR_EACH_ENTRY(n, &shader->nodes, head) { - n->visited = 0; - } - c_shader_dfs_without_rec(&shader->entry, node); -} - -static int c_shader_build_dominator_tree_rec(struct c_shader *shader, struct c_node *node) -{ - struct c_node_link *link, *nlink; - unsigned found = 0; - int r; - - if (node->done) - return 0; - node->done = 1; - LIST_FOR_EACH_ENTRY(link, &node->predecessors, head) { - /* if we remove this predecessor can we reach the current node ? */ - c_shader_dfs_without(shader, link->node); - if (node->visited == 0) { - /* we were unable to visit current node thus current - * predecessor is the immediate dominator of node, as - * their can be only one immediate dominator we break - */ - node->parent = link->node; - nlink = c_node_link_new(node); - if (nlink == NULL) - return -ENOMEM; - LIST_ADDTAIL(&nlink->head, &link->node->childs); - found = 1; - break; - } - } - /* this shouldn't happen there should at least be 1 denominator for each node */ - if (!found && node->opcode != C_OPCODE_ENTRY) { - fprintf(stderr, "invalid flow control graph node %p (%d) has no immediate dominator\n", - node, node->opcode); - return -EINVAL; - } - LIST_FOR_EACH_ENTRY(link, &node->predecessors, head) { - r = c_shader_build_dominator_tree_rec(shader, link->node); - if (r) - return r; - } - return 0; -} - -int c_shader_build_dominator_tree(struct c_shader *shader) -{ - struct c_node *node; - LIST_FOR_EACH_ENTRY(node, &shader->nodes, head) { - node->done = 0; - } - return c_shader_build_dominator_tree_rec(shader, &shader->end); -} diff --git a/src/gallium/drivers/r600/r600_compiler.h b/src/gallium/drivers/r600/r600_compiler.h deleted file mode 100644 index 77230aed73..0000000000 --- a/src/gallium/drivers/r600/r600_compiler.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef R600_COMPILER_H -#define R600_COMPILER_H - -#include "util/u_double_list.h" - -struct c_vector; - -/* operand are the basic source/destination of each operation */ -struct c_channel { - struct list_head head; - unsigned vindex; /**< index in vector X,Y,Z,W (0,1,2,3) */ - unsigned value; /**< immediate value 32bits */ - struct c_vector *vector; /**< vector to which it belongs */ -}; - -/* in GPU world most of the time operand are grouped into vector - * of 4 component this structure is mostly and handler to group - * operand into a same vector - */ -struct c_vector { - struct list_head head; - unsigned id; /**< vector uniq id */ - unsigned name; /**< semantic name */ - unsigned file; /**< operand file C_FILE_* */ - int sid; /**< semantic id */ - struct c_channel *channel[4]; /**< operands */ -}; - -#define C_PROGRAM_TYPE_VS 0 -#define C_PROGRAM_TYPE_FS 1 -#define C_PROGRAM_TYPE_COUNT 2 - -#define C_NODE_FLAG_ALU 1 -#define C_NODE_FLAG_FETCH 2 - -#define C_SWIZZLE_X 0 -#define C_SWIZZLE_Y 1 -#define C_SWIZZLE_Z 2 -#define C_SWIZZLE_W 3 -#define C_SWIZZLE_0 4 -#define C_SWIZZLE_1 5 -#define C_SWIZZLE_D 6 - -#define C_FILE_NULL 0 -#define C_FILE_CONSTANT 1 -#define C_FILE_INPUT 2 -#define C_FILE_OUTPUT 3 -#define C_FILE_TEMPORARY 4 -#define C_FILE_SAMPLER 5 -#define C_FILE_ADDRESS 6 -#define C_FILE_IMMEDIATE 7 -#define C_FILE_LOOP 8 -#define C_FILE_PREDICATE 9 -#define C_FILE_SYSTEM_VALUE 10 -#define C_FILE_RESOURCE 11 -#define C_FILE_COUNT 12 - -#define C_SEMANTIC_POSITION 0 -#define C_SEMANTIC_COLOR 1 -#define C_SEMANTIC_BCOLOR 2 /**< back-face color */ -#define C_SEMANTIC_FOG 3 -#define C_SEMANTIC_PSIZE 4 -#define C_SEMANTIC_GENERIC 5 -#define C_SEMANTIC_NORMAL 6 -#define C_SEMANTIC_FACE 7 -#define C_SEMANTIC_EDGEFLAG 8 -#define C_SEMANTIC_PRIMID 9 -#define C_SEMANTIC_INSTANCEID 10 -#define C_SEMANTIC_VERTEXID 11 -#define C_SEMANTIC_COUNT 12 /**< number of semantic values */ - -#define C_OPCODE_NOP 0 -#define C_OPCODE_MOV 1 -#define C_OPCODE_LIT 2 -#define C_OPCODE_RCP 3 -#define C_OPCODE_RSQ 4 -#define C_OPCODE_EXP 5 -#define C_OPCODE_LOG 6 -#define C_OPCODE_MUL 7 -#define C_OPCODE_ADD 8 -#define C_OPCODE_DP3 9 -#define C_OPCODE_DP4 10 -#define C_OPCODE_DST 11 -#define C_OPCODE_MIN 12 -#define C_OPCODE_MAX 13 -#define C_OPCODE_SLT 14 -#define C_OPCODE_SGE 15 -#define C_OPCODE_MAD 16 -#define C_OPCODE_SUB 17 -#define C_OPCODE_LRP 18 -#define C_OPCODE_CND 19 -/* gap */ -#define C_OPCODE_DP2A 21 -/* gap */ -#define C_OPCODE_FRC 24 -#define C_OPCODE_CLAMP 25 -#define C_OPCODE_FLR 26 -#define C_OPCODE_ROUND 27 -#define C_OPCODE_EX2 28 -#define C_OPCODE_LG2 29 -#define C_OPCODE_POW 30 -#define C_OPCODE_XPD 31 -/* gap */ -#define C_OPCODE_ABS 33 -#define C_OPCODE_RCC 34 -#define C_OPCODE_DPH 35 -#define C_OPCODE_COS 36 -#define C_OPCODE_DDX 37 -#define C_OPCODE_DDY 38 -#define C_OPCODE_KILP 39 /* predicated kill */ -#define C_OPCODE_PK2H 40 -#define C_OPCODE_PK2US 41 -#define C_OPCODE_PK4B 42 -#define C_OPCODE_PK4UB 43 -#define C_OPCODE_RFL 44 -#define C_OPCODE_SEQ 45 -#define C_OPCODE_SFL 46 -#define C_OPCODE_SGT 47 -#define C_OPCODE_SIN 48 -#define C_OPCODE_SLE 49 -#define C_OPCODE_SNE 50 -#define C_OPCODE_STR 51 -#define C_OPCODE_TEX 52 -#define C_OPCODE_TXD 53 -#define C_OPCODE_TXP 54 -#define C_OPCODE_UP2H 55 -#define C_OPCODE_UP2US 56 -#define C_OPCODE_UP4B 57 -#define C_OPCODE_UP4UB 58 -#define C_OPCODE_X2D 59 -#define C_OPCODE_ARA 60 -#define C_OPCODE_ARR 61 -#define C_OPCODE_BRA 62 -#define C_OPCODE_CAL 63 -#define C_OPCODE_RET 64 -#define C_OPCODE_SSG 65 /* SGN */ -#define C_OPCODE_CMP 66 -#define C_OPCODE_SCS 67 -#define C_OPCODE_TXB 68 -#define C_OPCODE_NRM 69 -#define C_OPCODE_DIV 70 -#define C_OPCODE_DP2 71 -#define C_OPCODE_TXL 72 -#define C_OPCODE_BRK 73 -#define C_OPCODE_IF 74 -#define C_OPCODE_BGNFOR 75 -#define C_OPCODE_REP 76 -#define C_OPCODE_ELSE 77 -#define C_OPCODE_ENDIF 78 -#define C_OPCODE_ENDFOR 79 -#define C_OPCODE_ENDREP 80 -#define C_OPCODE_PUSHA 81 -#define C_OPCODE_POPA 82 -#define C_OPCODE_CEIL 83 -#define C_OPCODE_I2F 84 -#define C_OPCODE_NOT 85 -#define C_OPCODE_TRUNC 86 -#define C_OPCODE_SHL 87 -/* gap */ -#define C_OPCODE_AND 89 -#define C_OPCODE_OR 90 -#define C_OPCODE_MOD 91 -#define C_OPCODE_XOR 92 -#define C_OPCODE_SAD 93 -#define C_OPCODE_TXF 94 -#define C_OPCODE_TXQ 95 -#define C_OPCODE_CONT 96 -#define C_OPCODE_EMIT 97 -#define C_OPCODE_ENDPRIM 98 -#define C_OPCODE_BGNLOOP 99 -#define C_OPCODE_BGNSUB 100 -#define C_OPCODE_ENDLOOP 101 -#define C_OPCODE_ENDSUB 102 -/* gap */ -#define C_OPCODE_NRM4 112 -#define C_OPCODE_CALLNZ 113 -#define C_OPCODE_IFC 114 -#define C_OPCODE_BREAKC 115 -#define C_OPCODE_KIL 116 /* conditional kill */ -#define C_OPCODE_END 117 /* aka HALT */ -/* gap */ -#define C_OPCODE_F2I 119 -#define C_OPCODE_IDIV 120 -#define C_OPCODE_IMAX 121 -#define C_OPCODE_IMIN 122 -#define C_OPCODE_INEG 123 -#define C_OPCODE_ISGE 124 -#define C_OPCODE_ISHR 125 -#define C_OPCODE_ISLT 126 -#define C_OPCODE_F2U 127 -#define C_OPCODE_U2F 128 -#define C_OPCODE_UADD 129 -#define C_OPCODE_UDIV 130 -#define C_OPCODE_UMAD 131 -#define C_OPCODE_UMAX 132 -#define C_OPCODE_UMIN 133 -#define C_OPCODE_UMOD 134 -#define C_OPCODE_UMUL 135 -#define C_OPCODE_USEQ 136 -#define C_OPCODE_USGE 137 -#define C_OPCODE_USHR 138 -#define C_OPCODE_USLT 139 -#define C_OPCODE_USNE 140 -#define C_OPCODE_SWITCH 141 -#define C_OPCODE_CASE 142 -#define C_OPCODE_DEFAULT 143 -#define C_OPCODE_ENDSWITCH 144 -#define C_OPCODE_VFETCH 145 -#define C_OPCODE_ENTRY 146 -#define C_OPCODE_ARL 147 -#define C_OPCODE_LAST 148 - -#define C_OPERAND_FLAG_ABS (1 << 0) -#define C_OPERAND_FLAG_NEG (1 << 1) - -struct c_operand { - struct c_vector *vector; - unsigned swizzle; - unsigned flag; -}; - -struct c_op { - unsigned ninput; - struct c_operand input[3]; - struct c_operand output; - unsigned opcode; -}; - -struct c_instruction { - struct list_head head; - unsigned nop; - struct c_op op[5]; -}; - -struct c_node; - -struct c_node_link { - struct list_head head; - struct c_node *node; -}; - -/** - * struct c_node - * - * @next: all node are in a double linked list, this point to - * next node - * @next: all node are in a double linked list, this point to - * previous node - * @predecessors: list of all predecessor nodes in the flow graph - * @successors: list of all sucessor nodes in the flow graph - * @parent: parent node in the depth first walk tree - * @childs: child nodes in the depth first walk tree - */ -struct c_node { - struct list_head head; - struct list_head predecessors; - struct list_head successors; - struct list_head childs; - struct c_node *parent; - struct list_head insts; - unsigned opcode; - unsigned visited; - unsigned done; - void *backend; -}; - -struct c_file { - unsigned nvectors; - struct list_head vectors; -}; - -struct c_shader { - unsigned nvectors; - struct c_file files[C_FILE_COUNT]; - struct list_head nodes; - struct c_node entry; - struct c_node end; - unsigned type; -}; - -int c_shader_init(struct c_shader *shader, unsigned type); -void c_shader_destroy(struct c_shader *shader); -struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid); -int c_shader_build_dominator_tree(struct c_shader *shader); -void c_shader_dump(struct c_shader *shader); - -void c_node_init(struct c_node *node); -int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction); -int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction); - -/* control flow graph functions */ -int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor); -struct c_node *c_node_cfg_new_after(struct c_node *predecessor); -struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor); - -struct c_vector *c_vector_new(void); - -#endif diff --git a/src/gallium/drivers/r600/r600_compiler_dump.c b/src/gallium/drivers/r600/r600_compiler_dump.c deleted file mode 100644 index bb022b7c29..0000000000 --- a/src/gallium/drivers/r600/r600_compiler_dump.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include -#include -#include "r600_compiler.h" - -static const char *c_file_swz[] = { - "x", - "y", - "z", - "w", - "0", - "1", - ".", -}; - -static const char *c_file_str[] = { - "NULL", - "CONSTANT", - "INPUT", - "OUTPUT", - "TEMPORARY", - "SAMPLER", - "ADDRESS", - "IMMEDIATE", - "LOOP", - "PREDICATE", - "SYSTEM_VALUE", -}; - -static const char *c_semantic_str[] = { - "POSITION", - "COLOR", - "BCOLOR", - "FOG", - "PSIZE", - "GENERIC", - "NORMAL", - "FACE", - "EDGEFLAG", - "PRIMID", - "INSTANCEID", -}; - -static const char *c_opcode_str[] = { - "ARL", - "MOV", - "LIT", - "RCP", - "RSQ", - "EXP", - "LOG", - "MUL", - "ADD", - "DP3", - "DP4", - "DST", - "MIN", - "MAX", - "SLT", - "SGE", - "MAD", - "SUB", - "LRP", - "CND", - "(INVALID)", - "DP2A", - "(INVALID)", - "(INVALID)", - "FRC", - "CLAMP", - "FLR", - "ROUND", - "EX2", - "LG2", - "POW", - "XPD", - "(INVALID)", - "ABS", - "RCC", - "DPH", - "COS", - "DDX", - "DDY", - "KILP", - "PK2H", - "PK2US", - "PK4B", - "PK4UB", - "RFL", - "SEQ", - "SFL", - "SGT", - "SIN", - "SLE", - "SNE", - "STR", - "TEX", - "TXD", - "TXP", - "UP2H", - "UP2US", - "UP4B", - "UP4UB", - "X2D", - "ARA", - "ARR", - "BRA", - "CAL", - "RET", - "SSG", - "CMP", - "SCS", - "TXB", - "NRM", - "DIV", - "DP2", - "TXL", - "BRK", - "IF", - "BGNFOR", - "REP", - "ELSE", - "ENDIF", - "ENDFOR", - "ENDREP", - "PUSHA", - "POPA", - "CEIL", - "I2F", - "NOT", - "TRUNC", - "SHL", - "(INVALID)", - "AND", - "OR", - "MOD", - "XOR", - "SAD", - "TXF", - "TXQ", - "CONT", - "EMIT", - "ENDPRIM", - "BGNLOOP", - "BGNSUB", - "ENDLOOP", - "ENDSUB", - "(INVALID)", - "(INVALID)", - "(INVALID)", - "(INVALID)", - "NOP", - "(INVALID)", - "(INVALID)", - "(INVALID)", - "(INVALID)", - "NRM4", - "CALLNZ", - "IFC", - "BREAKC", - "KIL", - "END", - "(INVALID)", - "F2I", - "IDIV", - "IMAX", - "IMIN", - "INEG", - "ISGE", - "ISHR", - "ISLT", - "F2U", - "U2F", - "UADD", - "UDIV", - "UMAD", - "UMAX", - "UMIN", - "UMOD", - "UMUL", - "USEQ", - "USGE", - "USHR", - "USLT", - "USNE", - "SWITCH", - "CASE", - "DEFAULT", - "ENDSWITCH", - "VFETCH", - "ENTRY", -}; - -static inline const char *c_get_name(const char *name[], unsigned i) -{ - return name[i]; -} - -static void pindent(unsigned indent) -{ - unsigned i; - for (i = 0; i < indent; i++) - fprintf(stderr, " "); -} - -static void c_node_dump(struct c_node *node, unsigned indent) -{ - struct c_instruction *i; - unsigned j, k; - - pindent(indent); fprintf(stderr, "# node %s\n", c_get_name(c_opcode_str, node->opcode)); - LIST_FOR_EACH_ENTRY(i, &node->insts, head) { - for (k = 0; k < i->nop; k++) { - pindent(indent); - fprintf(stderr, "%s", c_get_name(c_opcode_str, i->op[k].opcode)); - fprintf(stderr, " %s[%d][%s]", - c_get_name(c_file_str, i->op[k].output.vector->file), - i->op[k].output.vector->id, - c_get_name(c_file_swz, i->op[k].output.swizzle)); - for (j = 0; j < i->op[k].ninput; j++) { - fprintf(stderr, " %s[%d][%s]", - c_get_name(c_file_str, i->op[k].input[j].vector->file), - i->op[k].input[j].vector->id, - c_get_name(c_file_swz, i->op[k].input[j].swizzle)); - } - fprintf(stderr, ";\n"); - } - } -} - -static void c_shader_dump_rec(struct c_shader *shader, struct c_node *node, unsigned indent) -{ - struct c_node_link *link; - - c_node_dump(node, indent); - LIST_FOR_EACH_ENTRY(link, &node->childs, head) { - c_shader_dump_rec(shader, link->node, indent + 1); - } -} - -void c_shader_dump(struct c_shader *shader) -{ - c_shader_dump_rec(shader, &shader->entry, 0); -} diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c deleted file mode 100644 index 27ad8f1a18..0000000000 --- a/src/gallium/drivers/r600/r600_compiler_r600.c +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include "r600_screen.h" -#include "r600_context.h" -#include "r600_sq.h" - - -struct r600_alu_instruction { - unsigned copcode; - enum r600_instruction instruction; -}; - -static int r600_shader_alu_translate(struct r600_shader *rshader, - struct r600_shader_node *node, - struct c_instruction *instruction); -struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST]; -struct r600_instruction_info r600_instruction_info[]; - -int r600_shader_insert_fetch(struct c_shader *shader) -{ - struct c_vector *vi, *vr, *v, *nv; - struct c_instruction instruction; - int r; - - if (shader->type != C_PROGRAM_TYPE_VS) - return 0; - vi = c_shader_vector_new(shader, C_FILE_INPUT, C_SEMANTIC_VERTEXID, -1); - if (vi == NULL) - return -ENOMEM; - LIST_FOR_EACH_ENTRY_SAFE(v, nv, &shader->files[C_FILE_INPUT].vectors, head) { - if (v == vi) - continue; - vr = c_shader_vector_new(shader, C_FILE_RESOURCE, C_SEMANTIC_GENERIC, -1); - if (vr == NULL) - return -ENOMEM; - memset(&instruction, 0, sizeof(struct c_instruction)); - instruction.nop = 4; - instruction.op[0].opcode = C_OPCODE_VFETCH; - instruction.op[1].opcode = C_OPCODE_VFETCH; - instruction.op[2].opcode = C_OPCODE_VFETCH; - instruction.op[3].opcode = C_OPCODE_VFETCH; - instruction.op[0].ninput = 2; - instruction.op[1].ninput = 2; - instruction.op[2].ninput = 2; - instruction.op[3].ninput = 2; - instruction.op[0].output.vector = v; - instruction.op[1].output.vector = v; - instruction.op[2].output.vector = v; - instruction.op[3].output.vector = v; - instruction.op[0].input[0].vector = vi; - instruction.op[0].input[1].vector = vr; - instruction.op[1].input[0].vector = vi; - instruction.op[1].input[1].vector = vr; - instruction.op[2].input[0].vector = vi; - instruction.op[2].input[1].vector = vr; - instruction.op[3].input[0].vector = vi; - instruction.op[3].input[1].vector = vr; - instruction.op[0].output.swizzle = C_SWIZZLE_X; - instruction.op[1].output.swizzle = C_SWIZZLE_Y; - instruction.op[2].output.swizzle = C_SWIZZLE_Z; - instruction.op[3].output.swizzle = C_SWIZZLE_W; - r = c_node_add_new_instruction_head(&shader->entry, &instruction); - if (r) - return r; - LIST_DEL(&v->head); - shader->files[C_FILE_INPUT].nvectors--; - LIST_ADDTAIL(&v->head, &shader->files[C_FILE_TEMPORARY].vectors); - shader->files[C_FILE_TEMPORARY].nvectors++; - v->file = C_FILE_TEMPORARY; - } - return 0; -} - -void r600_shader_cleanup(struct r600_shader *rshader) -{ - struct r600_shader_node *n, *nn; - struct r600_shader_vfetch *vf, *nvf; - struct r600_shader_alu *alu, *nalu; - int i; - - if (rshader == NULL) - return; - if (rshader->gpr) { - for (i = 0; i < rshader->nvector; i++) { - free(rshader->gpr[i]); - } - free(rshader->gpr); - rshader->gpr = NULL; - } - LIST_FOR_EACH_ENTRY_SAFE(n, nn, &rshader->nodes, head) { - LIST_DEL(&n->head); - LIST_FOR_EACH_ENTRY_SAFE(vf, nvf, &n->vfetch, head) { - LIST_DEL(&vf->head); - free(vf); - } - LIST_FOR_EACH_ENTRY_SAFE(alu, nalu, &n->alu, head) { - LIST_DEL(&alu->head); - free(alu); - } - free(n); - } - free(rshader->bcode); - return; -} - -int r600_shader_vfetch_bytecode(struct r600_shader *rshader, - struct r600_shader_node *rnode, - struct r600_shader_vfetch *vfetch, - unsigned *cid) -{ - unsigned id = *cid; - - vfetch->cf_addr = id; - rshader->bcode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vfetch->src[1].sel) | - S_SQ_VTX_WORD0_SRC_GPR(vfetch->src[0].sel) | - S_SQ_VTX_WORD0_SRC_SEL_X(vfetch->src[0].sel) | - S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(0x1F); - rshader->bcode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vfetch->dst[0].chan) | - S_SQ_VTX_WORD1_DST_SEL_Y(vfetch->dst[1].chan) | - S_SQ_VTX_WORD1_DST_SEL_Z(vfetch->dst[2].chan) | - S_SQ_VTX_WORD1_DST_SEL_W(vfetch->dst[3].chan) | - S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) | - S_SQ_VTX_WORD1_GPR_DST_GPR(vfetch->dst[0].sel); - rshader->bcode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1); - rshader->bcode[id++] = 0; - *cid = id; - return 0; -} - -int r600_shader_update(struct r600_shader *rshader, enum pipe_format *resource_format) -{ - struct r600_shader_node *rnode; - struct r600_shader_vfetch *vfetch; - unsigned i; - - memcpy(rshader->resource_format, resource_format, - rshader->nresource * sizeof(enum pipe_format)); - LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) { - LIST_FOR_EACH_ENTRY(vfetch, &rnode->vfetch, head) { - const struct util_format_description *desc; - i = vfetch->cf_addr + 1; - rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_X; - rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Y; - rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Z; - rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_W; - desc = util_format_description(resource_format[vfetch->src[1].sel]); - if (desc == NULL) { - fprintf(stderr, "%s unknown format %d\n", __func__, resource_format[vfetch->src[1].sel]); - continue; - } - /* WARNING so far TGSI swizzle match R600 ones */ - rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_X(desc->swizzle[0]); - rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Y(desc->swizzle[1]); - rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Z(desc->swizzle[2]); - rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_W(desc->swizzle[3]); - } - } - return 0; -} - -int r600_shader_register(struct r600_shader *rshader) -{ - struct c_vector *v, *nv; - unsigned tid, cid, rid, i; - - rshader->nvector = rshader->cshader.nvectors; - rshader->gpr = calloc(rshader->nvector, sizeof(void*)); - if (rshader->gpr == NULL) - return -ENOMEM; - tid = 0; - cid = 0; - rid = 0; - /* alloc input first */ - LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_INPUT].vectors, head) { - nv = c_vector_new(); - if (nv == NULL) { - return -ENOMEM; - } - memcpy(nv, v, sizeof(struct c_vector)); - nv->id = tid++; - rshader->gpr[v->id] = nv; - } - for (i = 0; i < C_FILE_COUNT; i++) { - if (i == C_FILE_INPUT || i == C_FILE_IMMEDIATE) - continue; - LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[i].vectors, head) { - switch (v->file) { - case C_FILE_OUTPUT: - case C_FILE_TEMPORARY: - nv = c_vector_new(); - if (nv == NULL) { - return -ENOMEM; - } - memcpy(nv, v, sizeof(struct c_vector)); - nv->id = tid++; - rshader->gpr[v->id] = nv; - break; - case C_FILE_CONSTANT: - nv = c_vector_new(); - if (nv == NULL) { - return -ENOMEM; - } - memcpy(nv, v, sizeof(struct c_vector)); - nv->id = (cid++) + 256; - rshader->gpr[v->id] = nv; - break; - case C_FILE_RESOURCE: - nv = c_vector_new(); - if (nv == NULL) { - return -ENOMEM; - } - memcpy(nv, v, sizeof(struct c_vector)); - nv->id = (rid++); - rshader->gpr[v->id] = nv; - break; - default: - fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, v->file); - return -EINVAL; - } - } - } - rshader->ngpr = tid; - rshader->nconstant = cid; - rshader->nresource = rid; - return 0; -} - -int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle, - struct r600_shader_operand *operand) -{ - struct c_vector *tmp; - - /* Values [0,127] correspond to GPR[0..127]. - * Values [256,511] correspond to cfile constants c[0..255]. - * Other special values are shown in the list below. - * 248 SQ_ALU_SRC_0: special constant 0.0. - * 249 SQ_ALU_SRC_1: special constant 1.0 float. - * 250 SQ_ALU_SRC_1_INT: special constant 1 integer. - * 251 SQ_ALU_SRC_M_1_INT: special constant -1 integer. - * 252 SQ_ALU_SRC_0_5: special constant 0.5 float. - * 253 SQ_ALU_SRC_LITERAL: literal constant. - * 254 SQ_ALU_SRC_PV: previous vector result. - * 255 SQ_ALU_SRC_PS: previous scalar result. - */ - operand->vector = v; - operand->sel = 248; - operand->chan = 0; - operand->neg = 0; - operand->abs = 0; - if (v == NULL) - return 0; - if (v->file == C_FILE_IMMEDIATE) { - operand->sel = 253; - } else { - tmp = rshader->gpr[v->id]; - if (tmp == NULL) { - fprintf(stderr, "%s %d unknown register\n", __FILE__, __LINE__); - return -EINVAL; - } - operand->sel = tmp->id; - } - operand->chan = swizzle; - switch (swizzle) { - case C_SWIZZLE_X: - case C_SWIZZLE_Y: - case C_SWIZZLE_Z: - case C_SWIZZLE_W: - break; - case C_SWIZZLE_0: - operand->sel = 248; - operand->chan = 0; - break; - case C_SWIZZLE_1: - operand->sel = 249; - operand->chan = 0; - break; - default: - fprintf(stderr, "%s %d invalid swizzle %d\n", __FILE__, __LINE__, swizzle); - return -EINVAL; - } - return 0; -} - -static struct r600_shader_node *r600_shader_new_node(struct r600_shader *rshader, struct c_node *node) -{ - struct r600_shader_node *rnode; - - rnode = CALLOC_STRUCT(r600_shader_node); - if (rnode == NULL) - return NULL; - rnode->node = node; - LIST_INITHEAD(&rnode->vfetch); -fprintf(stderr, "------------------------ new node (%p %p)\n", &rnode->vfetch, rnode->vfetch.next); - LIST_INITHEAD(&rnode->alu); - LIST_ADDTAIL(&rnode->head, &rshader->nodes); - return rnode; -} - -static int r600_shader_add_vfetch(struct r600_shader *rshader, - struct r600_shader_node *node, - struct c_instruction *instruction) -{ - struct r600_shader_vfetch *vfetch; - struct r600_shader_node *rnode; - int r; - - if (instruction == NULL) - return 0; - if (instruction->op[0].opcode != C_OPCODE_VFETCH) - return 0; - if (!LIST_IS_EMPTY(&node->alu)) { - rnode = r600_shader_new_node(rshader, node->node); - if (rnode == NULL) - return -ENOMEM; - node = rnode; - } - vfetch = calloc(1, sizeof(struct r600_shader_vfetch)); - if (vfetch == NULL) - return -ENOMEM; - r = r600_shader_find_gpr(rshader, instruction->op[0].output.vector, 0, &vfetch->dst[0]); - if (r) - return r; - r = r600_shader_find_gpr(rshader, instruction->op[0].input[0].vector, 0, &vfetch->src[0]); - if (r) - return r; - r = r600_shader_find_gpr(rshader, instruction->op[0].input[1].vector, 0, &vfetch->src[1]); - if (r) - return r; - vfetch->dst[0].chan = C_SWIZZLE_X; - vfetch->dst[1].chan = C_SWIZZLE_Y; - vfetch->dst[2].chan = C_SWIZZLE_Z; - vfetch->dst[3].chan = C_SWIZZLE_W; - LIST_ADDTAIL(&vfetch->head, &node->vfetch); - node->nslot += 2; - return 0; -} - -static int r600_node_translate(struct r600_shader *rshader, struct c_node *node) -{ - struct c_instruction *instruction; - struct r600_shader_node *rnode; - int r; - - rnode = r600_shader_new_node(rshader, node); - if (rnode == NULL) - return -ENOMEM; - LIST_FOR_EACH_ENTRY(instruction, &node->insts, head) { - switch (instruction->op[0].opcode) { - case C_OPCODE_VFETCH: - r = r600_shader_add_vfetch(rshader, rnode, instruction); - if (r) { - fprintf(stderr, "%s %d vfetch failed\n", __func__, __LINE__); - return r; - } - break; - default: - r = r600_shader_alu_translate(rshader, rnode, instruction); - if (r) { - fprintf(stderr, "%s %d alu failed\n", __func__, __LINE__); - return r; - } - break; - } - } - return 0; -} - -int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node) -{ - struct c_node_link *link; - int r; - - if (node->opcode == C_OPCODE_END) - return 0; - r = r600_node_translate(rshader, node); - if (r) - return r; - LIST_FOR_EACH_ENTRY(link, &node->childs, head) { - r = r600_shader_translate_rec(rshader, link->node); - if (r) - return r; - } - return 0; -} - -static struct r600_shader_alu *r600_shader_insert_alu(struct r600_shader *rshader, struct r600_shader_node *node) -{ - struct r600_shader_alu *alu; - - alu = CALLOC_STRUCT(r600_shader_alu); - if (alu == NULL) - return NULL; - alu->alu[0].inst = INST_NOP; - alu->alu[1].inst = INST_NOP; - alu->alu[2].inst = INST_NOP; - alu->alu[3].inst = INST_NOP; - alu->alu[4].inst = INST_NOP; - alu->alu[0].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[1].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[2].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[3].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[4].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[1].dst.chan = 1; - alu->alu[2].dst.chan = 2; - alu->alu[3].dst.chan = 3; - LIST_ADDTAIL(&alu->head, &node->alu); - return alu; -} - -static int r600_shader_alu_translate(struct r600_shader *rshader, - struct r600_shader_node *node, - struct c_instruction *instruction) -{ - struct r600_shader_node *rnode; - struct r600_shader_alu *alu; - int i, j, r, litteral_lastcomp = -1; - - if (!LIST_IS_EMPTY(&node->vfetch)) { -fprintf(stderr, "------------------------ add node (%p %p)\n", &node->vfetch, node->vfetch.next); - rnode = r600_shader_new_node(rshader, node->node); - if (rnode == NULL) { - fprintf(stderr, "%s %d new node failed\n", __func__, __LINE__); - return -ENOMEM; - } - node = rnode; - } - - /* initialize alu */ - alu = r600_shader_insert_alu(rshader, node); - - /* check special operation like lit */ - - /* go through operation */ - for (i = 0; i < instruction->nop; i++) { - struct r600_alu_instruction *ainfo = &r600_alu_instruction[instruction->op[i].opcode]; - struct r600_instruction_info *iinfo = &r600_instruction_info[ainfo->instruction]; - unsigned comp; - - /* check that output is a valid component */ - comp = instruction->op[i].output.swizzle; - switch (comp) { - case C_SWIZZLE_X: - case C_SWIZZLE_Y: - case C_SWIZZLE_Z: - case C_SWIZZLE_W: - break; - case C_SWIZZLE_0: - case C_SWIZZLE_1: - default: - fprintf(stderr, "%s %d invalid output %d\n", __func__, __LINE__, comp); - return -EINVAL; - } - alu->alu[comp].inst = ainfo->instruction; - alu->alu[comp].opcode = iinfo->opcode; - alu->alu[comp].is_op3 = iinfo->is_op3; - for (j = 0; j < instruction->op[i].ninput; j++) { - r = r600_shader_find_gpr(rshader, instruction->op[i].input[j].vector, - instruction->op[i].input[j].swizzle, &alu->alu[comp].src[j]); - if (r) { - fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__); - return r; - } - if (instruction->op[i].input[j].vector->file == C_FILE_IMMEDIATE) { - r = instruction->op[i].input[j].swizzle; - switch (r) { - case C_SWIZZLE_X: - case C_SWIZZLE_Y: - case C_SWIZZLE_Z: - case C_SWIZZLE_W: - break; - case C_SWIZZLE_0: - case C_SWIZZLE_1: - default: - fprintf(stderr, "%s %d invalid input\n", __func__, __LINE__); - return -EINVAL; - } - alu->literal[r] = instruction->op[i].input[j].vector->channel[r]->value; - if (r > litteral_lastcomp) { - litteral_lastcomp = r; - } - } - } - r = r600_shader_find_gpr(rshader, instruction->op[i].output.vector, - instruction->op[i].output.swizzle, &alu->alu[comp].dst); - if (r) { - fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__); - return r; - } - } - switch (litteral_lastcomp) { - case 0: - case 1: - alu->nliteral = 2; - break; - case 2: - case 3: - alu->nliteral = 4; - break; - case -1: - default: - break; - } - for (i = 4; i >= 0; i--) { - if (alu->alu[i].inst != INST_NOP) { - alu->alu[i].last = 1; - alu->nalu = i + 1; - break; - } - } - return 0; -} - -void r600_shader_node_place(struct r600_shader *rshader) -{ - struct r600_shader_node *node, *nnode; - struct r600_shader_alu *alu, *nalu; - struct r600_shader_vfetch *vfetch, *nvfetch; - unsigned cf_id = 0, cf_addr = 0; - - rshader->ncf = 0; - rshader->nslot = 0; - LIST_FOR_EACH_ENTRY_SAFE(node, nnode, &rshader->nodes, head) { - LIST_FOR_EACH_ENTRY_SAFE(alu, nalu, &node->alu, head) { - node->nslot += alu->nalu; - node->nslot += alu->nliteral >> 1; - } - node->nfetch = 0; - LIST_FOR_EACH_ENTRY_SAFE(vfetch, nvfetch, &node->vfetch, head) { - node->nslot += 2; - node->nfetch += 1; - } - if (!LIST_IS_EMPTY(&node->vfetch)) { - /* fetch node need to be 16 bytes aligned*/ - cf_addr += 1; - cf_addr &= 0xFFFFFFFEUL; - } - node->cf_id = cf_id; - node->cf_addr = cf_addr; - cf_id += 2; - cf_addr += node->nslot * 2; - rshader->ncf++; - } - rshader->nslot = cf_addr; - LIST_FOR_EACH_ENTRY_SAFE(node, nnode, &rshader->nodes, head) { - node->cf_addr += cf_id * 2; - } - rshader->ncf += rshader->cshader.files[C_FILE_OUTPUT].nvectors; - rshader->ndw = rshader->ncf * 2 + rshader->nslot * 2; -} - -int r600_shader_legalize(struct r600_shader *rshader) -{ - return 0; -} - - -static int r600_cshader_legalize_rec(struct c_shader *shader, struct c_node *node) -{ - struct c_node_link *link; - struct c_instruction *i, *n; - struct c_operand operand; - unsigned k, inst; - int r; - - LIST_FOR_EACH_ENTRY(i, &node->insts, head) { - for (k = 0; k < i->nop; k++) { - switch (i->op[k].opcode) { - case C_OPCODE_SLT: - i->op[k].opcode = C_OPCODE_SGT; - memcpy(&operand, &i->op[k].input[0], sizeof(struct c_operand)); - memcpy(&i->op[k].input[0], &i->op[k].input[1], sizeof(struct c_operand)); - memcpy(&i->op[k].input[1], &operand, sizeof(struct c_operand)); - break; - default: - break; - } - inst = r600_alu_instruction[i->op[k].opcode].instruction; - if (r600_instruction_info[inst].is_trans && k < (i->nop -1)) { - /* split trans opcode */ - n = CALLOC_STRUCT(c_instruction); - if (n == NULL) - return -ENOMEM; - for (n->nop = 0, k = k + 1; k < i->nop; k++, n->nop++) { - memcpy(&n->op[n->nop - 0], &i->op[k], sizeof(struct c_op)); - } - i->nop -= n->nop; - LIST_ADD(&n->head, &i->head); - } - } - } - LIST_FOR_EACH_ENTRY(link, &node->childs, head) { - r = r600_cshader_legalize_rec(shader, link->node); - if (r) { - return r; - } - } - return 0; -} - -int r600_cshader_legalize(struct c_shader *shader) -{ - return r600_cshader_legalize_rec(shader, &shader->entry); -} - - -struct r600_instruction_info r600_instruction_info[] = { - {INST_ADD, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, 0, 0}, - {INST_MUL, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, 0, 0}, - {INST_MUL_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL_IEEE, 0, 0}, - {INST_MAX, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, 0, 0}, - {INST_MIN, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN, 0, 0}, - {INST_MAX_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_DX10, 0, 0}, - {INST_MIN_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_DX10, 0, 0}, - {INST_SETE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE, 0, 0}, - {INST_SETGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, 0, 0}, - {INST_SETGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE, 0, 0}, - {INST_SETNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, 0, 0}, - {INST_SETE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_DX10, 0, 0}, - {INST_SETGT_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_DX10, 0, 0}, - {INST_SETGE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_DX10, 0, 0}, - {INST_SETNE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_DX10, 0, 0}, - {INST_FRACT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT, 0, 0}, - {INST_TRUNC, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC, 0, 0}, - {INST_CEIL, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CEIL, 0, 0}, - {INST_RNDNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RNDNE, 0, 0}, - {INST_FLOOR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR, 0, 0}, - {INST_MOVA, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA, 0, 0}, - {INST_MOVA_FLOOR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR, 0, 0}, - {INST_MOVA_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT, 0, 0}, - {INST_MOV, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, 0, 0}, - {INST_NOP, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 0, 0}, - {INST_PRED_SETGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT, 0, 0}, - {INST_PRED_SETGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT, 0, 0}, - {INST_PRED_SETE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE, 0, 0}, - {INST_PRED_SETGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT, 0, 0}, - {INST_PRED_SETGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE, 0, 0}, - {INST_PRED_SETNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE, 0, 0}, - {INST_PRED_SET_INV, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV, 0, 0}, - {INST_PRED_SET_POP, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP, 0, 0}, - {INST_PRED_SET_CLR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR, 0, 0}, - {INST_PRED_SET_RESTORE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE, 0, 0}, - {INST_PRED_SETE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH, 0, 0}, - {INST_PRED_SETGT_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH, 0, 0}, - {INST_PRED_SETGE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH, 0, 0}, - {INST_PRED_SETNE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH, 0, 0}, - {INST_KILLE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE, 0, 0}, - {INST_KILLGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT, 0, 0}, - {INST_KILLGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE, 0, 0}, - {INST_KILLNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE, 0, 0}, - {INST_AND_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_AND_INT, 0, 0}, - {INST_OR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_OR_INT, 0, 0}, - {INST_XOR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_XOR_INT, 0, 0}, - {INST_NOT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOT_INT, 0, 0}, - {INST_ADD_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD_INT, 0, 0}, - {INST_SUB_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SUB_INT, 0, 0}, - {INST_MAX_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_INT, 0, 0}, - {INST_MIN_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_INT, 0, 0}, - {INST_MAX_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_UINT, 0, 0}, - {INST_MIN_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_UINT, 0, 0}, - {INST_SETE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_INT, 0, 0}, - {INST_SETGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_INT, 0, 0}, - {INST_SETGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_INT, 0, 0}, - {INST_SETNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_INT, 0, 0}, - {INST_SETGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_UINT, 0, 0}, - {INST_SETGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_UINT, 0, 0}, - {INST_KILLGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT, 0, 0}, - {INST_KILLGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT, 0, 0}, - {INST_PRED_SETE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT, 0, 0}, - {INST_PRED_SETGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT, 0, 0}, - {INST_PRED_SETGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT, 0, 0}, - {INST_PRED_SETNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT, 0, 0}, - {INST_KILLE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT, 0, 0}, - {INST_KILLGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT, 0, 0}, - {INST_KILLGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT, 0, 0}, - {INST_KILLNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT, 0, 0}, - {INST_PRED_SETE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT, 0, 0}, - {INST_PRED_SETGT_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT, 0, 0}, - {INST_PRED_SETGE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT, 0, 0}, - {INST_PRED_SETNE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT, 0, 0}, - {INST_PRED_SETLT_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT, 0, 0}, - {INST_PRED_SETLE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT, 0, 0}, - {INST_DOT4, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, 0, 0}, - {INST_DOT4_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE, 0, 0}, - {INST_CUBE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE, 0, 0}, - {INST_MAX4, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4, 0, 0}, - {INST_MOVA_GPR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT, 0, 0}, - {INST_EXP_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE, 1, 0}, - {INST_LOG_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED, 1, 0}, - {INST_LOG_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE, 1, 0}, - {INST_RECIP_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED, 1, 0}, - {INST_RECIP_FF, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF, 1, 0}, - {INST_RECIP_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, 1, 0}, - {INST_RECIPSQRT_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED, 1, 0}, - {INST_RECIPSQRT_FF, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF, 1, 0}, - {INST_RECIPSQRT_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, 1, 0}, - {INST_SQRT_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE, 1, 0}, - {INST_FLT_TO_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT, 1, 0}, - {INST_INT_TO_FLT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT, 1, 0}, - {INST_UINT_TO_FLT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT, 1, 0}, - {INST_SIN, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN, 1, 0}, - {INST_COS, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS, 1, 0}, - {INST_ASHR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT, 1, 0}, - {INST_LSHR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT, 1, 0}, - {INST_LSHL_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT, 1, 0}, - {INST_MULLO_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT, 1, 0}, - {INST_MULHI_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT, 1, 0}, - {INST_MULLO_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT, 1, 0}, - {INST_MULHI_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT, 1, 0}, - {INST_RECIP_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT, 1, 0}, - {INST_RECIP_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT, 1, 0}, - {INST_FLT_TO_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT, 1, 0}, - {INST_MUL_LIT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT, 1, 1}, - {INST_MUL_LIT_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2, 1, 1}, - {INST_MUL_LIT_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4, 1, 1}, - {INST_MUL_LIT_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2, 1, 1}, - {INST_MULADD, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, 0, 1}, - {INST_MULADD_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M2, 0, 1}, - {INST_MULADD_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M4, 0, 1}, - {INST_MULADD_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_D2, 0, 1}, - {INST_MULADD_IEEE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE, 0, 1}, - {INST_MULADD_IEEE_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M2, 0, 1}, - {INST_MULADD_IEEE_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M4, 0, 1}, - {INST_MULADD_IEEE_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_D2, 0, 1}, - {INST_CNDE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE, 0, 1}, - {INST_CNDGT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT, 0, 1}, - {INST_CNDGE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE, 0, 1}, - {INST_CNDE_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE_INT, 0, 1}, - {INST_CNDGT_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT_INT, 0, 1}, - {INST_CNDGE_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE_INT, 0, 1}, -}; - -struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST] = { - {C_OPCODE_NOP, INST_NOP}, - {C_OPCODE_MOV, INST_MOV}, - {C_OPCODE_LIT, INST_NOP}, - {C_OPCODE_RCP, INST_RECIP_IEEE}, - {C_OPCODE_RSQ, INST_RECIPSQRT_IEEE}, - {C_OPCODE_EXP, INST_EXP_IEEE}, - {C_OPCODE_LOG, INST_LOG_IEEE}, - {C_OPCODE_MUL, INST_MUL}, - {C_OPCODE_ADD, INST_ADD}, - {C_OPCODE_DP3, INST_DOT4}, - {C_OPCODE_DP4, INST_DOT4}, - {C_OPCODE_DST, INST_NOP}, - {C_OPCODE_MIN, INST_MIN}, - {C_OPCODE_MAX, INST_MAX}, - {C_OPCODE_SLT, INST_NOP}, - {C_OPCODE_SGE, INST_NOP}, - {C_OPCODE_MAD, INST_MULADD}, - {C_OPCODE_SUB, INST_COUNT}, - {C_OPCODE_LRP, INST_NOP}, - {C_OPCODE_CND, INST_NOP}, - {20, INST_NOP}, - {C_OPCODE_DP2A, INST_NOP}, - {22, INST_NOP}, - {23, INST_NOP}, - {C_OPCODE_FRC, INST_NOP}, - {C_OPCODE_CLAMP, INST_NOP}, - {C_OPCODE_FLR, INST_NOP}, - {C_OPCODE_ROUND, INST_NOP}, - {C_OPCODE_EX2, INST_NOP}, - {C_OPCODE_LG2, INST_NOP}, - {C_OPCODE_POW, INST_NOP}, - {C_OPCODE_XPD, INST_NOP}, - {32, INST_NOP}, - {C_OPCODE_ABS, INST_COUNT}, - {C_OPCODE_RCC, INST_NOP}, - {C_OPCODE_DPH, INST_NOP}, - {C_OPCODE_COS, INST_COS}, - {C_OPCODE_DDX, INST_NOP}, - {C_OPCODE_DDY, INST_NOP}, - {C_OPCODE_KILP, INST_NOP}, - {C_OPCODE_PK2H, INST_NOP}, - {C_OPCODE_PK2US, INST_NOP}, - {C_OPCODE_PK4B, INST_NOP}, - {C_OPCODE_PK4UB, INST_NOP}, - {C_OPCODE_RFL, INST_NOP}, - {C_OPCODE_SEQ, INST_NOP}, - {C_OPCODE_SFL, INST_NOP}, - {C_OPCODE_SGT, INST_SETGT}, - {C_OPCODE_SIN, INST_SIN}, - {C_OPCODE_SLE, INST_NOP}, - {C_OPCODE_SNE, INST_NOP}, - {C_OPCODE_STR, INST_NOP}, - {C_OPCODE_TEX, INST_NOP}, - {C_OPCODE_TXD, INST_NOP}, - {C_OPCODE_TXP, INST_NOP}, - {C_OPCODE_UP2H, INST_NOP}, - {C_OPCODE_UP2US, INST_NOP}, - {C_OPCODE_UP4B, INST_NOP}, - {C_OPCODE_UP4UB, INST_NOP}, - {C_OPCODE_X2D, INST_NOP}, - {C_OPCODE_ARA, INST_NOP}, - {C_OPCODE_ARR, INST_NOP}, - {C_OPCODE_BRA, INST_NOP}, - {C_OPCODE_CAL, INST_NOP}, - {C_OPCODE_RET, INST_NOP}, - {C_OPCODE_SSG, INST_NOP}, - {C_OPCODE_CMP, INST_NOP}, - {C_OPCODE_SCS, INST_NOP}, - {C_OPCODE_TXB, INST_NOP}, - {C_OPCODE_NRM, INST_NOP}, - {C_OPCODE_DIV, INST_NOP}, - {C_OPCODE_DP2, INST_NOP}, - {C_OPCODE_TXL, INST_NOP}, - {C_OPCODE_BRK, INST_NOP}, - {C_OPCODE_IF, INST_NOP}, - {C_OPCODE_BGNFOR, INST_NOP}, - {C_OPCODE_REP, INST_NOP}, - {C_OPCODE_ELSE, INST_NOP}, - {C_OPCODE_ENDIF, INST_NOP}, - {C_OPCODE_ENDFOR, INST_NOP}, - {C_OPCODE_ENDREP, INST_NOP}, - {C_OPCODE_PUSHA, INST_NOP}, - {C_OPCODE_POPA, INST_NOP}, - {C_OPCODE_CEIL, INST_NOP}, - {C_OPCODE_I2F, INST_NOP}, - {C_OPCODE_NOT, INST_NOP}, - {C_OPCODE_TRUNC, INST_NOP}, - {C_OPCODE_SHL, INST_NOP}, - {88, INST_NOP}, - {C_OPCODE_AND, INST_NOP}, - {C_OPCODE_OR, INST_NOP}, - {C_OPCODE_MOD, INST_NOP}, - {C_OPCODE_XOR, INST_NOP}, - {C_OPCODE_SAD, INST_NOP}, - {C_OPCODE_TXF, INST_NOP}, - {C_OPCODE_TXQ, INST_NOP}, - {C_OPCODE_CONT, INST_NOP}, - {C_OPCODE_EMIT, INST_NOP}, - {C_OPCODE_ENDPRIM, INST_NOP}, - {C_OPCODE_BGNLOOP, INST_NOP}, - {C_OPCODE_BGNSUB, INST_NOP}, - {C_OPCODE_ENDLOOP, INST_NOP}, - {C_OPCODE_ENDSUB, INST_NOP}, - {103, INST_NOP}, - {104, INST_NOP}, - {105, INST_NOP}, - {106, INST_NOP}, - {107, INST_NOP}, - {108, INST_NOP}, - {109, INST_NOP}, - {110, INST_NOP}, - {111, INST_NOP}, - {C_OPCODE_NRM4, INST_NOP}, - {C_OPCODE_CALLNZ, INST_NOP}, - {C_OPCODE_IFC, INST_NOP}, - {C_OPCODE_BREAKC, INST_NOP}, - {C_OPCODE_KIL, INST_NOP}, - {C_OPCODE_END, INST_NOP}, - {118, INST_NOP}, - {C_OPCODE_F2I, INST_NOP}, - {C_OPCODE_IDIV, INST_NOP}, - {C_OPCODE_IMAX, INST_NOP}, - {C_OPCODE_IMIN, INST_NOP}, - {C_OPCODE_INEG, INST_NOP}, - {C_OPCODE_ISGE, INST_NOP}, - {C_OPCODE_ISHR, INST_NOP}, - {C_OPCODE_ISLT, INST_NOP}, - {C_OPCODE_F2U, INST_NOP}, - {C_OPCODE_U2F, INST_NOP}, - {C_OPCODE_UADD, INST_NOP}, - {C_OPCODE_UDIV, INST_NOP}, - {C_OPCODE_UMAD, INST_NOP}, - {C_OPCODE_UMAX, INST_NOP}, - {C_OPCODE_UMIN, INST_NOP}, - {C_OPCODE_UMOD, INST_NOP}, - {C_OPCODE_UMUL, INST_NOP}, - {C_OPCODE_USEQ, INST_NOP}, - {C_OPCODE_USGE, INST_NOP}, - {C_OPCODE_USHR, INST_NOP}, - {C_OPCODE_USLT, INST_NOP}, - {C_OPCODE_USNE, INST_NOP}, - {C_OPCODE_SWITCH, INST_NOP}, - {C_OPCODE_CASE, INST_NOP}, - {C_OPCODE_DEFAULT, INST_NOP}, - {C_OPCODE_ENDSWITCH, INST_NOP}, - {C_OPCODE_VFETCH, INST_NOP}, - {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 deleted file mode 100644 index 0b43942866..0000000000 --- a/src/gallium/drivers/r600/r600_compiler_r700.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include -#include -#include -#include "r600_context.h" -#include "r700_sq.h" - -static int r700_shader_cf_node_bytecode(struct r600_shader *rshader, - struct r600_shader_node *rnode, - unsigned *cid) -{ - unsigned id = *cid; - - if (rnode->nfetch) { - rshader->bcode[id++] = S_SQ_CF_WORD0_ADDR(rnode->cf_addr >> 1); - rshader->bcode[id++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) | - S_SQ_CF_WORD1_BARRIER(1) | - S_SQ_CF_WORD1_COUNT(rnode->nfetch - 1); - } else { - rshader->bcode[id++] = S_SQ_CF_ALU_WORD0_ADDR(rnode->cf_addr >> 1); - rshader->bcode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) | - S_SQ_CF_ALU_WORD1_BARRIER(1) | - S_SQ_CF_ALU_WORD1_COUNT(rnode->nslot - 1); - } - *cid = id; - return 0; -} - -static int r700_shader_cf_output_bytecode(struct r600_shader *rshader, - struct c_vector *v, - unsigned *cid, - unsigned end) -{ - struct r600_shader_operand out; - unsigned id = *cid; - int r; - - r = r600_shader_find_gpr(rshader, v, 0, &out); - if (r) - return r; - rshader->bcode[id + 0] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(out.sel) | - S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(3); - rshader->bcode[id + 1] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(0) | - S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(1) | - S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(2) | - S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(3) | - S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(1) | - S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE) | - S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(end); - switch (v->name) { - case C_SEMANTIC_POSITION: - rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(60) | - S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS); - break; - case C_SEMANTIC_COLOR: - if (rshader->cshader.type == C_PROGRAM_TYPE_VS) { - rshader->output[rshader->noutput].gpr = out.sel; - rshader->output[rshader->noutput].sid = v->sid; - rshader->output[rshader->noutput].name = v->name; - rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) | - S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM); - } else { - rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(0) | - S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL); - } - break; - case C_SEMANTIC_GENERIC: - rshader->output[rshader->noutput].gpr = out.sel; - rshader->output[rshader->noutput].sid = v->sid; - rshader->output[rshader->noutput].name = v->name; - rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) | - S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM); - break; - default: - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - *cid = id + 2; - return 0; -} - -static int r700_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; -} - -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 c_vector *v; - unsigned id, end; - int r; - - r = r600_shader_register(rshader); - if (r) { - fprintf(stderr, "%s %d register allocation failed\n", __FILE__, __LINE__); - return r; - } - r = r600_shader_translate_rec(rshader, &shader->entry); - if (r) { - fprintf(stderr, "%s %d translation failed\n", __FILE__, __LINE__); - return r; - } - r = r600_shader_legalize(rshader); - if (r) { - fprintf(stderr, "%s %d legalize failed\n", __FILE__, __LINE__); - return r; - } - r600_shader_node_place(rshader); - rshader->bcode = malloc(rshader->ndw * 4); - if (rshader->bcode == NULL) - return -ENOMEM; - LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) { - id = rnode->cf_addr; - LIST_FOR_EACH_ENTRY(vfetch, &rnode->vfetch, head) { - r = r600_shader_vfetch_bytecode(rshader, rnode, vfetch, &id); - if (r) - return r; - } - 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) { - r = r700_shader_cf_node_bytecode(rshader, rnode, &id); - if (r) - return r; - } - LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_OUTPUT].vectors, head) { - end = 0; - if (v->head.next == &rshader->cshader.files[C_FILE_OUTPUT].vectors) - end = 1; - r = r700_shader_cf_output_bytecode(rshader, v, &id, end); - if (r) - return r; - } - LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_INPUT].vectors, head) { - rshader->input[rshader->ninput].gpr = rshader->ninput; - rshader->input[rshader->ninput].sid = v->sid; - rshader->input[rshader->ninput].name = v->name; - rshader->ninput++; - } - return 0; -} diff --git a/src/gallium/drivers/r600/r600_compiler_tgsi.c b/src/gallium/drivers/r600/r600_compiler_tgsi.c deleted file mode 100644 index 172cf154a3..0000000000 --- a/src/gallium/drivers/r600/r600_compiler_tgsi.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include "r600_shader.h" -#include "r600_context.h" - -struct tgsi_shader { - struct c_vector **v[TGSI_FILE_COUNT]; - struct tgsi_shader_info info; - struct tgsi_parse_context parser; - const struct tgsi_token *tokens; - struct c_shader *shader; - struct c_node *node; -}; - -static unsigned tgsi_file_to_c_file(unsigned file); -static unsigned tgsi_sname_to_c_sname(unsigned sname); -static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode); - -static int tgsi_shader_init(struct tgsi_shader *ts, - const struct tgsi_token *tokens, - struct c_shader *shader) -{ - int i; - - ts->shader = shader; - ts->tokens = tokens; - tgsi_scan_shader(ts->tokens, &ts->info); - tgsi_parse_init(&ts->parser, ts->tokens); - /* initialize to NULL in case of error */ - for (i = 0; i < C_FILE_COUNT; i++) { - ts->v[i] = NULL; - } - for (i = 0; i < TGSI_FILE_COUNT; i++) { - if (ts->info.file_count[i] > 0) { - ts->v[i] = calloc(ts->info.file_count[i], sizeof(void*)); - if (ts->v[i] == NULL) { - fprintf(stderr, "%s:%d unsupported %d %d\n", __func__, __LINE__, i, ts->info.file_count[i]); - return -ENOMEM; - } - } - } - return 0; -} - -static void tgsi_shader_destroy(struct tgsi_shader *ts) -{ - int i; - - for (i = 0; i < TGSI_FILE_COUNT; i++) { - free(ts->v[i]); - } - tgsi_parse_free(&ts->parser); -} - -static int ntransform_declaration(struct tgsi_shader *ts) -{ - struct tgsi_full_declaration *fd = &ts->parser.FullToken.FullDeclaration; - struct c_vector *v; - unsigned file; - unsigned name; - int sid; - int i; - - if (fd->Declaration.Dimension) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - for (i = fd->Range.First ; i <= fd->Range.Last; i++) { - sid = i; - name = C_SEMANTIC_GENERIC; - file = tgsi_file_to_c_file(fd->Declaration.File); - if (file == TGSI_FILE_NULL) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fd->Declaration.Semantic) { - name = tgsi_sname_to_c_sname(fd->Semantic.Name); - sid = fd->Semantic.Index; - } - v = c_shader_vector_new(ts->shader, file, name, sid); - if (v == NULL) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -ENOMEM; - } - ts->v[fd->Declaration.File][i] = v; - } - return 0; -} - -static int ntransform_immediate(struct tgsi_shader *ts) -{ - struct tgsi_full_immediate *fd = &ts->parser.FullToken.FullImmediate; - struct c_vector *v; - unsigned file; - unsigned name; - - if (fd->Immediate.DataType != TGSI_IMM_FLOAT32) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - name = C_SEMANTIC_GENERIC; - file = C_FILE_IMMEDIATE; - v = c_shader_vector_new(ts->shader, file, name, 0); - if (v == NULL) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -ENOMEM; - } - v->channel[0]->value = fd->u[0].Uint; - v->channel[1]->value = fd->u[1].Uint; - v->channel[2]->value = fd->u[2].Uint; - v->channel[3]->value = fd->u[3].Uint; - ts->v[TGSI_FILE_IMMEDIATE][0] = v; - return 0; -} - -static int ntransform_instruction(struct tgsi_shader *ts) -{ - struct tgsi_full_instruction *fi = &ts->parser.FullToken.FullInstruction; - struct c_shader *shader = ts->shader; - struct c_instruction instruction; - unsigned opcode; - int i, j, r; - - if (fi->Instruction.NumDstRegs > 1) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fi->Instruction.Saturate) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fi->Instruction.Predicate) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fi->Instruction.Label) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fi->Instruction.Texture) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - for (i = 0; i < fi->Instruction.NumSrcRegs; i++) { - if (fi->Src[i].Register.Indirect || - fi->Src[i].Register.Dimension || - fi->Src[i].Register.Absolute) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - } - for (i = 0; i < fi->Instruction.NumDstRegs; i++) { - if (fi->Dst[i].Register.Indirect || fi->Dst[i].Register.Dimension) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - } - r = tgsi_opcode_to_c_opcode(fi->Instruction.Opcode, &opcode); - if (r) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return r; - } - if (opcode == C_OPCODE_END) { - return c_node_cfg_link(ts->node, &shader->end); - } - /* FIXME add flow instruction handling */ - memset(&instruction, 0, sizeof(struct c_instruction)); - instruction.nop = 0; - for (j = 0; j < 4; j++) { - instruction.op[instruction.nop].opcode = opcode; - instruction.op[instruction.nop].ninput = fi->Instruction.NumSrcRegs; - for (i = 0; i < fi->Instruction.NumSrcRegs; i++) { - instruction.op[instruction.nop].input[i].vector = ts->v[fi->Src[i].Register.File][fi->Src[i].Register.Index]; - switch (j) { - case 0: - instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleX; - break; - case 1: - instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleY; - break; - case 2: - instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleZ; - break; - case 3: - instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleW; - break; - default: - return -EINVAL; - } - } - instruction.op[instruction.nop].output.vector = ts->v[fi->Dst[0].Register.File][fi->Dst[0].Register.Index]; - switch (j) { - case 0: - instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_X : C_SWIZZLE_D; - break; - case 1: - instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Y : C_SWIZZLE_D; - break; - case 2: - instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Z : C_SWIZZLE_D; - break; - case 3: - instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_W : C_SWIZZLE_D; - break; - default: - return -EINVAL; - } - instruction.nop++; - } - return c_node_add_new_instruction(ts->node, &instruction); -} - -int c_shader_from_tgsi(struct c_shader *shader, unsigned type, - const struct tgsi_token *tokens) -{ - struct tgsi_shader ts; - int r = 0; - - c_shader_init(shader, type); - r = tgsi_shader_init(&ts, tokens, shader); - if (r) - goto out_err; - ts.shader = shader; - ts.node = &shader->entry; - while (!tgsi_parse_end_of_tokens(&ts.parser)) { - tgsi_parse_token(&ts.parser); - switch (ts.parser.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_IMMEDIATE: - r = ntransform_immediate(&ts); - if (r) - goto out_err; - break; - case TGSI_TOKEN_TYPE_DECLARATION: - r = ntransform_declaration(&ts); - if (r) - goto out_err; - break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - r = ntransform_instruction(&ts); - if (r) - goto out_err; - break; - default: - r = -EINVAL; - goto out_err; - } - } - tgsi_shader_destroy(&ts); - return 0; -out_err: - c_shader_destroy(shader); - tgsi_shader_destroy(&ts); - return r; -} - -static unsigned tgsi_file_to_c_file(unsigned file) -{ - switch (file) { - case TGSI_FILE_CONSTANT: - return C_FILE_CONSTANT; - case TGSI_FILE_INPUT: - return C_FILE_INPUT; - case TGSI_FILE_OUTPUT: - return C_FILE_OUTPUT; - case TGSI_FILE_TEMPORARY: - return C_FILE_TEMPORARY; - case TGSI_FILE_SAMPLER: - return C_FILE_SAMPLER; - case TGSI_FILE_ADDRESS: - return C_FILE_ADDRESS; - case TGSI_FILE_IMMEDIATE: - return C_FILE_IMMEDIATE; - case TGSI_FILE_PREDICATE: - return C_FILE_PREDICATE; - case TGSI_FILE_SYSTEM_VALUE: - return C_FILE_SYSTEM_VALUE; - case TGSI_FILE_NULL: - return C_FILE_NULL; - default: - fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, file); - return C_FILE_NULL; - } -} - -static unsigned tgsi_sname_to_c_sname(unsigned sname) -{ - switch (sname) { - case TGSI_SEMANTIC_POSITION: - return C_SEMANTIC_POSITION; - case TGSI_SEMANTIC_COLOR: - return C_SEMANTIC_COLOR; - case TGSI_SEMANTIC_BCOLOR: - return C_SEMANTIC_BCOLOR; - case TGSI_SEMANTIC_FOG: - return C_SEMANTIC_FOG; - case TGSI_SEMANTIC_PSIZE: - return C_SEMANTIC_PSIZE; - case TGSI_SEMANTIC_GENERIC: - return C_SEMANTIC_GENERIC; - case TGSI_SEMANTIC_NORMAL: - return C_SEMANTIC_NORMAL; - case TGSI_SEMANTIC_FACE: - return C_SEMANTIC_FACE; - case TGSI_SEMANTIC_EDGEFLAG: - return C_SEMANTIC_EDGEFLAG; - case TGSI_SEMANTIC_PRIMID: - return C_SEMANTIC_PRIMID; - case TGSI_SEMANTIC_INSTANCEID: - return C_SEMANTIC_INSTANCEID; - default: - return C_SEMANTIC_GENERIC; - } -} - -static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode) -{ - switch (opcode) { - case TGSI_OPCODE_MOV: - *copcode = C_OPCODE_MOV; - return 0; - case TGSI_OPCODE_MUL: - *copcode = C_OPCODE_MUL; - return 0; - case TGSI_OPCODE_MAD: - *copcode = C_OPCODE_MAD; - return 0; - case TGSI_OPCODE_END: - *copcode = C_OPCODE_END; - return 0; - case TGSI_OPCODE_ARL: - *copcode = C_OPCODE_ARL; - return 0; - case TGSI_OPCODE_LIT: - *copcode = C_OPCODE_LIT; - return 0; - case TGSI_OPCODE_RCP: - *copcode = C_OPCODE_RCP; - return 0; - case TGSI_OPCODE_RSQ: - *copcode = C_OPCODE_RSQ; - return 0; - case TGSI_OPCODE_EXP: - *copcode = C_OPCODE_EXP; - return 0; - case TGSI_OPCODE_LOG: - *copcode = C_OPCODE_LOG; - return 0; - case TGSI_OPCODE_ADD: - *copcode = C_OPCODE_ADD; - return 0; - case TGSI_OPCODE_DP3: - *copcode = C_OPCODE_DP3; - return 0; - case TGSI_OPCODE_DP4: - *copcode = C_OPCODE_DP4; - return 0; - case TGSI_OPCODE_DST: - *copcode = C_OPCODE_DST; - return 0; - case TGSI_OPCODE_MIN: - *copcode = C_OPCODE_MIN; - return 0; - case TGSI_OPCODE_MAX: - *copcode = C_OPCODE_MAX; - return 0; - case TGSI_OPCODE_SLT: - *copcode = C_OPCODE_SLT; - return 0; - case TGSI_OPCODE_SGE: - *copcode = C_OPCODE_SGE; - return 0; - case TGSI_OPCODE_SUB: - *copcode = C_OPCODE_SUB; - return 0; - case TGSI_OPCODE_LRP: - *copcode = C_OPCODE_LRP; - return 0; - case TGSI_OPCODE_CND: - *copcode = C_OPCODE_CND; - return 0; - case TGSI_OPCODE_DP2A: - *copcode = C_OPCODE_DP2A; - return 0; - case TGSI_OPCODE_FRC: - *copcode = C_OPCODE_FRC; - return 0; - case TGSI_OPCODE_CLAMP: - *copcode = C_OPCODE_CLAMP; - return 0; - case TGSI_OPCODE_FLR: - *copcode = C_OPCODE_FLR; - return 0; - case TGSI_OPCODE_ROUND: - *copcode = C_OPCODE_ROUND; - return 0; - case TGSI_OPCODE_EX2: - *copcode = C_OPCODE_EX2; - return 0; - case TGSI_OPCODE_LG2: - *copcode = C_OPCODE_LG2; - return 0; - case TGSI_OPCODE_POW: - *copcode = C_OPCODE_POW; - return 0; - case TGSI_OPCODE_XPD: - *copcode = C_OPCODE_XPD; - return 0; - case TGSI_OPCODE_ABS: - *copcode = C_OPCODE_ABS; - return 0; - case TGSI_OPCODE_RCC: - *copcode = C_OPCODE_RCC; - return 0; - case TGSI_OPCODE_DPH: - *copcode = C_OPCODE_DPH; - return 0; - case TGSI_OPCODE_COS: - *copcode = C_OPCODE_COS; - return 0; - case TGSI_OPCODE_DDX: - *copcode = C_OPCODE_DDX; - return 0; - case TGSI_OPCODE_DDY: - *copcode = C_OPCODE_DDY; - return 0; - case TGSI_OPCODE_KILP: - *copcode = C_OPCODE_KILP; - return 0; - case TGSI_OPCODE_PK2H: - *copcode = C_OPCODE_PK2H; - return 0; - case TGSI_OPCODE_PK2US: - *copcode = C_OPCODE_PK2US; - return 0; - case TGSI_OPCODE_PK4B: - *copcode = C_OPCODE_PK4B; - return 0; - case TGSI_OPCODE_PK4UB: - *copcode = C_OPCODE_PK4UB; - return 0; - case TGSI_OPCODE_RFL: - *copcode = C_OPCODE_RFL; - return 0; - case TGSI_OPCODE_SEQ: - *copcode = C_OPCODE_SEQ; - return 0; - case TGSI_OPCODE_SFL: - *copcode = C_OPCODE_SFL; - return 0; - case TGSI_OPCODE_SGT: - *copcode = C_OPCODE_SGT; - return 0; - case TGSI_OPCODE_SIN: - *copcode = C_OPCODE_SIN; - return 0; - case TGSI_OPCODE_SLE: - *copcode = C_OPCODE_SLE; - return 0; - case TGSI_OPCODE_SNE: - *copcode = C_OPCODE_SNE; - return 0; - case TGSI_OPCODE_STR: - *copcode = C_OPCODE_STR; - return 0; - case TGSI_OPCODE_TEX: - *copcode = C_OPCODE_TEX; - return 0; - case TGSI_OPCODE_TXD: - *copcode = C_OPCODE_TXD; - return 0; - case TGSI_OPCODE_TXP: - *copcode = C_OPCODE_TXP; - return 0; - case TGSI_OPCODE_UP2H: - *copcode = C_OPCODE_UP2H; - return 0; - case TGSI_OPCODE_UP2US: - *copcode = C_OPCODE_UP2US; - return 0; - case TGSI_OPCODE_UP4B: - *copcode = C_OPCODE_UP4B; - return 0; - case TGSI_OPCODE_UP4UB: - *copcode = C_OPCODE_UP4UB; - return 0; - case TGSI_OPCODE_X2D: - *copcode = C_OPCODE_X2D; - return 0; - case TGSI_OPCODE_ARA: - *copcode = C_OPCODE_ARA; - return 0; - case TGSI_OPCODE_ARR: - *copcode = C_OPCODE_ARR; - return 0; - case TGSI_OPCODE_BRA: - *copcode = C_OPCODE_BRA; - return 0; - case TGSI_OPCODE_CAL: - *copcode = C_OPCODE_CAL; - return 0; - case TGSI_OPCODE_RET: - *copcode = C_OPCODE_RET; - return 0; - case TGSI_OPCODE_SSG: - *copcode = C_OPCODE_SSG; - return 0; - case TGSI_OPCODE_CMP: - *copcode = C_OPCODE_CMP; - return 0; - case TGSI_OPCODE_SCS: - *copcode = C_OPCODE_SCS; - return 0; - case TGSI_OPCODE_TXB: - *copcode = C_OPCODE_TXB; - return 0; - case TGSI_OPCODE_NRM: - *copcode = C_OPCODE_NRM; - return 0; - case TGSI_OPCODE_DIV: - *copcode = C_OPCODE_DIV; - return 0; - case TGSI_OPCODE_DP2: - *copcode = C_OPCODE_DP2; - return 0; - case TGSI_OPCODE_TXL: - *copcode = C_OPCODE_TXL; - return 0; - case TGSI_OPCODE_BRK: - *copcode = C_OPCODE_BRK; - return 0; - case TGSI_OPCODE_IF: - *copcode = C_OPCODE_IF; - return 0; - case TGSI_OPCODE_ELSE: - *copcode = C_OPCODE_ELSE; - return 0; - case TGSI_OPCODE_ENDIF: - *copcode = C_OPCODE_ENDIF; - return 0; - case TGSI_OPCODE_PUSHA: - *copcode = C_OPCODE_PUSHA; - return 0; - case TGSI_OPCODE_POPA: - *copcode = C_OPCODE_POPA; - return 0; - case TGSI_OPCODE_CEIL: - *copcode = C_OPCODE_CEIL; - return 0; - case TGSI_OPCODE_I2F: - *copcode = C_OPCODE_I2F; - return 0; - case TGSI_OPCODE_NOT: - *copcode = C_OPCODE_NOT; - return 0; - case TGSI_OPCODE_TRUNC: - *copcode = C_OPCODE_TRUNC; - return 0; - case TGSI_OPCODE_SHL: - *copcode = C_OPCODE_SHL; - return 0; - case TGSI_OPCODE_AND: - *copcode = C_OPCODE_AND; - return 0; - case TGSI_OPCODE_OR: - *copcode = C_OPCODE_OR; - return 0; - case TGSI_OPCODE_MOD: - *copcode = C_OPCODE_MOD; - return 0; - case TGSI_OPCODE_XOR: - *copcode = C_OPCODE_XOR; - return 0; - case TGSI_OPCODE_SAD: - *copcode = C_OPCODE_SAD; - return 0; - case TGSI_OPCODE_TXF: - *copcode = C_OPCODE_TXF; - return 0; - case TGSI_OPCODE_TXQ: - *copcode = C_OPCODE_TXQ; - return 0; - case TGSI_OPCODE_CONT: - *copcode = C_OPCODE_CONT; - return 0; - case TGSI_OPCODE_EMIT: - *copcode = C_OPCODE_EMIT; - return 0; - case TGSI_OPCODE_ENDPRIM: - *copcode = C_OPCODE_ENDPRIM; - return 0; - case TGSI_OPCODE_BGNLOOP: - *copcode = C_OPCODE_BGNLOOP; - return 0; - case TGSI_OPCODE_BGNSUB: - *copcode = C_OPCODE_BGNSUB; - return 0; - case TGSI_OPCODE_ENDLOOP: - *copcode = C_OPCODE_ENDLOOP; - return 0; - case TGSI_OPCODE_ENDSUB: - *copcode = C_OPCODE_ENDSUB; - return 0; - case TGSI_OPCODE_NOP: - *copcode = C_OPCODE_NOP; - return 0; - case TGSI_OPCODE_NRM4: - *copcode = C_OPCODE_NRM4; - return 0; - case TGSI_OPCODE_CALLNZ: - *copcode = C_OPCODE_CALLNZ; - return 0; - case TGSI_OPCODE_IFC: - *copcode = C_OPCODE_IFC; - return 0; - case TGSI_OPCODE_BREAKC: - *copcode = C_OPCODE_BREAKC; - return 0; - case TGSI_OPCODE_KIL: - *copcode = C_OPCODE_KIL; - return 0; - case TGSI_OPCODE_F2I: - *copcode = C_OPCODE_F2I; - return 0; - case TGSI_OPCODE_IDIV: - *copcode = C_OPCODE_IDIV; - return 0; - case TGSI_OPCODE_IMAX: - *copcode = C_OPCODE_IMAX; - return 0; - case TGSI_OPCODE_IMIN: - *copcode = C_OPCODE_IMIN; - return 0; - case TGSI_OPCODE_INEG: - *copcode = C_OPCODE_INEG; - return 0; - case TGSI_OPCODE_ISGE: - *copcode = C_OPCODE_ISGE; - return 0; - case TGSI_OPCODE_ISHR: - *copcode = C_OPCODE_ISHR; - return 0; - case TGSI_OPCODE_ISLT: - *copcode = C_OPCODE_ISLT; - return 0; - case TGSI_OPCODE_F2U: - *copcode = C_OPCODE_F2U; - return 0; - case TGSI_OPCODE_U2F: - *copcode = C_OPCODE_U2F; - return 0; - case TGSI_OPCODE_UADD: - *copcode = C_OPCODE_UADD; - return 0; - case TGSI_OPCODE_UDIV: - *copcode = C_OPCODE_UDIV; - return 0; - case TGSI_OPCODE_UMAD: - *copcode = C_OPCODE_UMAD; - return 0; - case TGSI_OPCODE_UMAX: - *copcode = C_OPCODE_UMAX; - return 0; - case TGSI_OPCODE_UMIN: - *copcode = C_OPCODE_UMIN; - return 0; - case TGSI_OPCODE_UMOD: - *copcode = C_OPCODE_UMOD; - return 0; - case TGSI_OPCODE_UMUL: - *copcode = C_OPCODE_UMUL; - return 0; - case TGSI_OPCODE_USEQ: - *copcode = C_OPCODE_USEQ; - return 0; - case TGSI_OPCODE_USGE: - *copcode = C_OPCODE_USGE; - return 0; - case TGSI_OPCODE_USHR: - *copcode = C_OPCODE_USHR; - return 0; - case TGSI_OPCODE_USLT: - *copcode = C_OPCODE_USLT; - return 0; - case TGSI_OPCODE_USNE: - *copcode = C_OPCODE_USNE; - return 0; - case TGSI_OPCODE_SWITCH: - *copcode = C_OPCODE_SWITCH; - return 0; - case TGSI_OPCODE_CASE: - *copcode = C_OPCODE_CASE; - return 0; - case TGSI_OPCODE_DEFAULT: - *copcode = C_OPCODE_DEFAULT; - return 0; - case TGSI_OPCODE_ENDSWITCH: - *copcode = C_OPCODE_ENDSWITCH; - return 0; - default: - fprintf(stderr, "%s:%d unsupported opcode %d\n", __func__, __LINE__, opcode); - return -EINVAL; - } -} diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c index 05575b5767..3c5195f79e 100644 --- a/src/gallium/drivers/r600/r600_context.c +++ b/src/gallium/drivers/r600/r600_context.c @@ -55,7 +55,7 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags, */ if (!dc) radeon_ctx_dump_bof(rctx->ctx, "gallium.bof"); -#if 0 +#if 1 radeon_ctx_submit(rctx->ctx); #endif rctx->ctx = radeon_ctx_decref(rctx->ctx); diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index f27ff58ed4..669aaec0b2 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -40,7 +40,6 @@ struct r600_vertex_elements_state }; struct r600_pipe_shader { - unsigned type; struct r600_shader shader; struct radeon_bo *bo; struct radeon_state *state; @@ -92,8 +91,10 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader); struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, - unsigned type, const struct tgsi_token *tokens); int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader); +#define R600_ERR(fmt, args...) \ + fprintf(stderr, "EE %s/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args) + #endif diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index f7d6e10663..4a6cf40c26 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -19,40 +19,112 @@ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jerome Glisse */ -#include -#include -#include -#include -#include -#include +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_scan.h" +#include "util/u_format.h" #include "r600_screen.h" #include "r600_context.h" +#include "r600_shader.h" +#include "r600_asm.h" +#include "r600_sq.h" #include "r600d.h" +#include +#include + +static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader); + +static int r600_shader_update(struct pipe_context *ctx, struct r600_shader *shader) +{ + struct r600_context *rctx = r600_context(ctx); + const struct util_format_description *desc; + enum pipe_format resource_format[160]; + unsigned i, nresources = 0; + struct r600_bc *bc = &shader->bc; + struct r600_bc_cf *cf; + struct r600_bc_vtx *vtx; + + if (shader->processor_type != TGSI_PROCESSOR_VERTEX) + return 0; + for (i = 0; i < rctx->vertex_elements->count; i++) { + resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format; + } + LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { + switch (cf->inst) { + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) { + desc = util_format_description(resource_format[vtx->buffer_id]); + if (desc == NULL) { + R600_ERR("unknown format %d\n", resource_format[vtx->buffer_id]); + return -EINVAL; + } + vtx->dst_sel_x = desc->swizzle[0]; + vtx->dst_sel_y = desc->swizzle[1]; + vtx->dst_sel_z = desc->swizzle[2]; + vtx->dst_sel_w = desc->swizzle[3]; + } + break; + default: + break; + } + } + return r600_bc_build(&shader->bc); +} + +struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, + const struct tgsi_token *tokens) +{ + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader); + int r; + +fprintf(stderr, "--------------------------------------------------------------\n"); +tgsi_dump(tokens, 0); + if (rpshader == NULL) + return NULL; + rpshader->shader.family = radeon_get_family(rscreen->rw); + r = r600_shader_from_tgsi(tokens, &rpshader->shader); + if (r) { + R600_ERR("translation from TGSI failed !\n"); + goto out_err; + } + r = r600_bc_build(&rpshader->shader.bc); + if (r) { + R600_ERR("building bytecode failed !\n"); + goto out_err; + } +fprintf(stderr, "______________________________________________________________\n"); + return rpshader; +out_err: + free(rpshader); + return NULL; +} static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) { struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_shader *rshader = &rpshader->shader; struct radeon_state *state; - unsigned i, tmp; + unsigned i, j, tmp; rpshader->state = radeon_state_decref(rpshader->state); state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER); if (state == NULL) return -ENOMEM; - for (i = 0; i < rshader->noutput; i += 4) { - tmp = rshader->output[i].sid; - tmp |= rshader->output[i + 1].sid << 8; - tmp |= rshader->output[i + 2].sid << 16; - tmp |= rshader->output[i + 3].sid << 24; - state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp; - } - state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1); - state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr); + for (i = 0; i < 10; i++) { + state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i] = 0; + } + for (i = 0, j = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name != TGSI_SEMANTIC_POSITION) { + tmp = rshader->output[i].sid << ((j & 3) * 8); + state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + j / 4] |= tmp; + j++; + } + } + state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2); + state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->bc.ngpr); rpshader->state = state; rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo); @@ -81,7 +153,7 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) | S_0286CC_PERSP_GRADIENT_ENA(1); state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000; - state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr); + state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->bc.ngpr); state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002; rpshader->state = state; rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); @@ -100,21 +172,21 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r /* copy new shader */ radeon_bo_decref(rscreen->rw, rpshader->bo); rpshader->bo = NULL; - rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4, + rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->bc.ndw * 4, 4096, NULL); if (rpshader->bo == NULL) { return -ENOMEM; } radeon_bo_map(rscreen->rw, rpshader->bo); - memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4); + memcpy(rpshader->bo->data, rshader->bc.bytecode, rshader->bc.ndw * 4); radeon_bo_unmap(rscreen->rw, rpshader->bo); /* build state */ rshader->flat_shade = rctx->flat_shade; - switch (rpshader->type) { - case C_PROGRAM_TYPE_VS: + switch (rshader->processor_type) { + case TGSI_PROCESSOR_VERTEX: r = r600_pipe_shader_vs(ctx, rpshader); break; - case C_PROGRAM_TYPE_FS: + case TGSI_PROCESSOR_FRAGMENT: r = r600_pipe_shader_ps(ctx, rpshader); break; default: @@ -124,104 +196,610 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r return r; } -struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens) +int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) { - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader); - struct r600_shader *rshader = &rpshader->shader; + struct r600_context *rctx = r600_context(ctx); 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, "<< %s\n", rshader->r6xx_compile ? "R600" : "R700"); - tgsi_dump(tokens, 0); - fprintf(stderr, "--------------------------------------------------------------\n"); - r = c_shader_from_tgsi(&rshader->cshader, type, tokens); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + return -EINVAL; + /* there should be enough input */ + if (rctx->vertex_elements->count < rpshader->shader.bc.nresource) { + R600_ERR("%d resources provided, expecting %d\n", + rctx->vertex_elements->count, rpshader->shader.bc.nresource); + return -EINVAL; } - r = r600_shader_insert_fetch(&rshader->cshader); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + r = r600_shader_update(ctx, &rpshader->shader); + if (r) + return r; + return r600_pipe_shader(ctx, rpshader); +} + +struct r600_shader_tgsi_instruction; + +struct r600_shader_ctx { + struct tgsi_shader_info info; + struct tgsi_parse_context parse; + const struct tgsi_token *tokens; + unsigned type; + unsigned file_offset[TGSI_FILE_COUNT]; + unsigned temp_reg; + struct r600_shader_tgsi_instruction *inst_info; + struct r600_bc *bc; + struct r600_shader *shader; +}; + +struct r600_shader_tgsi_instruction { + unsigned tgsi_opcode; + unsigned is_op3; + unsigned r600_opcode; + int (*process)(struct r600_shader_ctx *ctx); +}; + +static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[]; + +static int tgsi_is_supported(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *i = &ctx->parse.FullToken.FullInstruction; + int j; + + if (i->Instruction.NumDstRegs > 1) { + R600_ERR("too many dst (%d)\n", i->Instruction.NumDstRegs); + return -EINVAL; } - r = c_shader_build_dominator_tree(&rshader->cshader); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + if (i->Instruction.Saturate) { + R600_ERR("staturate unsupported\n"); + return -EINVAL; } - r = r600_cshader_legalize(&rshader->cshader); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + if (i->Instruction.Predicate) { + R600_ERR("predicate unsupported\n"); + return -EINVAL; } - c_shader_dump(&rshader->cshader); - r = r700_shader_translate(rshader); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + if (i->Instruction.Label) { + R600_ERR("label unsupported\n"); + return -EINVAL; } -#if 1 -#if 0 - fprintf(stderr, "--------------------------------------------------------------\n"); - for (int i = 0; i < rshader->ndw; i++) { - fprintf(stderr, "0x%08X\n", rshader->bcode[i]); + if (i->Instruction.Texture) { + R600_ERR("texture unsupported\n"); + return -EINVAL; } -#endif - fprintf(stderr, ">>\n\n"); -#endif - return rpshader; + for (j = 0; j < i->Instruction.NumSrcRegs; j++) { + if (i->Src[j].Register.Indirect || + i->Src[j].Register.Dimension || + i->Src[j].Register.Absolute) { + R600_ERR("unsupported src (indirect|dimension|absolute)\n"); + return -EINVAL; + } + } + for (j = 0; j < i->Instruction.NumDstRegs; j++) { + if (i->Dst[j].Register.Indirect || i->Dst[j].Register.Dimension) { + R600_ERR("unsupported dst (indirect|dimension)\n"); + return -EINVAL; + } + } + return 0; } -void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +static int tgsi_declaration(struct r600_shader_ctx *ctx) { - struct r600_screen *rscreen = r600_screen(ctx->screen); + struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration; + struct r600_bc_vtx vtx; + unsigned i; + int r; - if (rpshader == NULL) - return; - radeon_bo_decref(rscreen->rw, rpshader->bo); - rpshader->bo = NULL; - r600_shader_cleanup(&rpshader->shader); - FREE(rpshader); + switch (d->Declaration.File) { + case TGSI_FILE_INPUT: + i = ctx->shader->ninput++; + ctx->shader->input[i].name = d->Semantic.Name; + ctx->shader->input[i].sid = d->Semantic.Index; + ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i; + if (ctx->type == TGSI_PROCESSOR_VERTEX) { + /* turn input into fetch */ + memset(&vtx, 0, sizeof(struct r600_bc_vtx)); + vtx.inst = 0; + vtx.fetch_type = 0; + vtx.buffer_id = i; + /* register containing the index into the buffer */ + vtx.src_gpr = 0; + vtx.src_sel_x = 0; + vtx.mega_fetch_count = 0x1F; + vtx.dst_gpr = ctx->shader->input[i].gpr; + vtx.dst_sel_x = 0; + vtx.dst_sel_y = 1; + vtx.dst_sel_z = 2; + vtx.dst_sel_w = 3; + r = r600_bc_add_vtx(ctx->bc, &vtx); + if (r) + return r; + } + break; + case TGSI_FILE_OUTPUT: + i = ctx->shader->noutput++; + ctx->shader->output[i].name = d->Semantic.Name; + ctx->shader->output[i].sid = d->Semantic.Index; + ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + i; + break; + case TGSI_FILE_CONSTANT: + case TGSI_FILE_TEMPORARY: + break; + default: + R600_ERR("unsupported file %d declaration\n", d->Declaration.File); + return -EINVAL; + } + return 0; } -int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader) { - struct r600_context *rctx = r600_context(ctx); - struct r600_shader *rshader; - enum pipe_format resource_format[160]; - unsigned i, nresources = 0; - int r; + struct tgsi_full_immediate *immediate; + struct r600_shader_ctx ctx; + struct r600_bc_output output; + unsigned opcode; + int i, r = 0, pos0; + u32 value[4]; - if (rpshader == NULL) - return -EINVAL; - rshader = &rpshader->shader; - switch (rpshader->type) { - case C_PROGRAM_TYPE_VS: - for (i = 0; i < rctx->vertex_elements->count; i++) { - resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format; + ctx.bc = &shader->bc; + ctx.shader = shader; + r = r600_bc_init(ctx.bc, shader->family); + if (r) + return r; + ctx.tokens = tokens; + tgsi_scan_shader(tokens, &ctx.info); + tgsi_parse_init(&ctx.parse, tokens); + ctx.type = ctx.parse.FullHeader.Processor.Processor; + shader->processor_type = ctx.type; + + /* register allocations */ + /* Values [0,127] correspond to GPR[0..127]. + * Values [256,511] correspond to cfile constants c[0..255]. + * Other special values are shown in the list below. + * 248 SQ_ALU_SRC_0: special constant 0.0. + * 249 SQ_ALU_SRC_1: special constant 1.0 float. + * 250 SQ_ALU_SRC_1_INT: special constant 1 integer. + * 251 SQ_ALU_SRC_M_1_INT: special constant -1 integer. + * 252 SQ_ALU_SRC_0_5: special constant 0.5 float. + * 253 SQ_ALU_SRC_LITERAL: literal constant. + * 254 SQ_ALU_SRC_PV: previous vector result. + * 255 SQ_ALU_SRC_PS: previous scalar result. + */ + for (i = 0; i < TGSI_FILE_COUNT; i++) { + ctx.file_offset[i] = 0; + } + if (ctx.type == TGSI_PROCESSOR_VERTEX) { + ctx.file_offset[TGSI_FILE_INPUT] = 1; + } + ctx.file_offset[TGSI_FILE_OUTPUT] = ctx.file_offset[TGSI_FILE_INPUT] + + ctx.info.file_count[TGSI_FILE_INPUT]; + ctx.file_offset[TGSI_FILE_TEMPORARY] = ctx.file_offset[TGSI_FILE_OUTPUT] + + ctx.info.file_count[TGSI_FILE_OUTPUT]; + ctx.file_offset[TGSI_FILE_CONSTANT] = 256; + ctx.file_offset[TGSI_FILE_IMMEDIATE] = 253; + ctx.temp_reg = ctx.file_offset[TGSI_FILE_TEMPORARY] + + ctx.info.file_count[TGSI_FILE_TEMPORARY]; + + while (!tgsi_parse_end_of_tokens(&ctx.parse)) { + tgsi_parse_token(&ctx.parse); + switch (ctx.parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_IMMEDIATE: +// R600_ERR("TGSI_TOKEN_TYPE_IMMEDIATE unsupported\n"); + immediate = &ctx.parse.FullToken.FullImmediate; + value[0] = immediate->u[0].Uint; + value[1] = immediate->u[1].Uint; + value[2] = immediate->u[2].Uint; + value[3] = immediate->u[3].Uint; + break; + case TGSI_TOKEN_TYPE_DECLARATION: + r = tgsi_declaration(&ctx); + if (r) + goto out_err; + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + r = tgsi_is_supported(&ctx); + if (r) + goto out_err; + opcode = ctx.parse.FullToken.FullInstruction.Instruction.Opcode; + ctx.inst_info = &r600_shader_tgsi_instruction[opcode]; + r = ctx.inst_info->process(&ctx); + if (r) + goto out_err; + r = r600_bc_add_literal(ctx.bc, value); + if (r) + goto out_err; + break; + default: + R600_ERR("unsupported token type %d\n", ctx.parse.FullToken.Token.Type); + r = -EINVAL; + goto out_err; + } + } + /* export output */ + for (i = 0, pos0 = 0; i < shader->noutput; i++) { + memset(&output, 0, sizeof(struct r600_bc_output)); + output.gpr = shader->output[i].gpr; + output.elem_size = 3; + output.swizzle_x = 0; + output.swizzle_y = 1; + output.swizzle_z = 2; + output.swizzle_w = 3; + output.barrier = 1; + output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; + output.array_base = i - pos0; + output.inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE; + switch (ctx.type == TGSI_PROCESSOR_VERTEX) { + case TGSI_PROCESSOR_VERTEX: + if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { + output.array_base = 60; + output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; + /* position doesn't count in array_base */ + pos0 = 1; + } + break; + case TGSI_PROCESSOR_FRAGMENT: + if (shader->output[i].name == TGSI_SEMANTIC_COLOR) { + output.array_base = 0; + output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + } else { + R600_ERR("unsupported fragment output name %d\n", shader->output[i].name); + r = -EINVAL; + goto out_err; + } + break; + default: + R600_ERR("unsupported processor type %d\n", ctx.type); + r = -EINVAL; + goto out_err; } + if (i == (shader->noutput - 1)) { + output.end_of_program = 1; + } + r = r600_bc_add_output(ctx.bc, &output); + if (r) + goto out_err; + } + tgsi_parse_free(&ctx.parse); + return 0; +out_err: + tgsi_parse_free(&ctx.parse); + return r; +} + +static int tgsi_unsupported(struct r600_shader_ctx *ctx) +{ + R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode); + return -EINVAL; +} + +static int tgsi_end(struct r600_shader_ctx *ctx) +{ + return 0; +} + +static int tgsi_src(struct r600_shader_ctx *ctx, + const struct tgsi_full_src_register *tgsi_src, + unsigned swizzle, + struct r600_bc_alu_src *r600_src) +{ + r600_src->sel = tgsi_src->Register.Index; + if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) { + r600_src->sel = 0; + } + r600_src->sel += ctx->file_offset[tgsi_src->Register.File]; + switch (swizzle) { + case 0: + r600_src->chan = tgsi_src->Register.SwizzleX; break; - default: + case 1: + r600_src->chan = tgsi_src->Register.SwizzleY; break; - } - /* there should be enough input */ - if (nresources < rshader->nresource) + case 2: + r600_src->chan = tgsi_src->Register.SwizzleZ; + break; + case 3: + r600_src->chan = tgsi_src->Register.SwizzleW; + break; + default: return -EINVAL; - /* FIXME compare resources */ - r = r600_shader_update(rshader, resource_format); - if (r) - return r; - return r600_pipe_shader(ctx, rpshader); + } + return 0; +} + +static int tgsi_dst(struct r600_shader_ctx *ctx, + const struct tgsi_full_dst_register *tgsi_dst, + unsigned swizzle, + struct r600_bc_alu_dst *r600_dst) +{ + r600_dst->sel = tgsi_dst->Register.Index; + r600_dst->sel += ctx->file_offset[tgsi_dst->Register.File]; + r600_dst->chan = swizzle; + r600_dst->write = 1; + return 0; +} + +static int tgsi_op2(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, j, r; + + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + } else { + alu.inst = ctx->inst_info->r600_opcode; + for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { + r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]); + if (r) + return r; + } + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + } + /* handle some special cases */ + switch (ctx->inst_info->tgsi_opcode) { + case TGSI_OPCODE_SUB: + alu.src[1].neg = 1; + break; + case TGSI_OPCODE_DP2: + if (i > 1) { + alu.src[0].sel = alu.src[1].sel = 248; + alu.src[0].chan = alu.src[1].chan = 0; + } + break; + case TGSI_OPCODE_DP3: + if (i > 2) { + alu.src[0].sel = alu.src[1].sel = 248; + alu.src[0].chan = alu.src[1].chan = 0; + } + break; + default: + break; + } + if (i == 3) { + alu.last = 1; + } + alu.nliteral = 0; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + +static int tgsi_slt(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, r; + + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + } else { + alu.inst = ctx->inst_info->r600_opcode; + r = tgsi_src(ctx, &inst->Src[0], i, &alu.src[1]); + if (r) + return r; + r = tgsi_src(ctx, &inst->Src[1], i, &alu.src[0]); + if (r) + return r; + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + } + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; } + +static int tgsi_op3(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, j, r; + + /* do it in 2 step as op3 doesn't support writemask */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = ctx->inst_info->r600_opcode; + for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { + r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]); + if (r) + return r; + } + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + alu.is_op3 = 1; + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + } else { + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = i; + } + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + +static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { + {TGSI_OPCODE_ARL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MOV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2}, + {TGSI_OPCODE_LIT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_RCP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_RSQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_EXP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_LOG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MUL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2}, + {TGSI_OPCODE_ADD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2}, + {TGSI_OPCODE_DP3, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_op2}, + {TGSI_OPCODE_DP4, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_op2}, + {TGSI_OPCODE_DST, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, tgsi_op2}, + {TGSI_OPCODE_SLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, tgsi_slt}, + {TGSI_OPCODE_SGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MAD, 1, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, tgsi_op3}, + {TGSI_OPCODE_SUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2}, + {TGSI_OPCODE_LRP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {20, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DP2A, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {22, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {23, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_FRC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CLAMP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_FLR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ROUND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_EX2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_LG2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_POW, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_XPD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {32, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ABS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_RCC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DPH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_COS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DDX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DDY, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_KILP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* predicated kill */ + {TGSI_OPCODE_PK2H, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_PK2US, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_PK4B, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_PK4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_RFL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SEQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SFL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SGT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SLE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_STR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TEX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UP2H, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UP2US, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UP4B, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UP4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_X2D, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ARA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BRA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CAL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_RET, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SSG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* SGN */ + {TGSI_OPCODE_CMP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SCS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_NRM, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DP2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_op2}, + {TGSI_OPCODE_TXL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BRK, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {75, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {76, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ELSE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDIF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {79, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {80, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_PUSHA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_POPA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CEIL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_I2F, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_NOT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TRUNC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SHL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {88, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_AND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_OR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MOD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_XOR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SAD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CONT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_EMIT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDPRIM, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BGNLOOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BGNSUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDLOOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDSUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {103, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {104, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {105, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {106, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_NOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {108, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {109, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {110, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {111, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_NRM4, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CALLNZ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IFC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BREAKC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_KIL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* conditional kill */ + {TGSI_OPCODE_END, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_end}, /* aka HALT */ + /* gap */ + {118, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_F2I, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IDIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IMAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IMIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_INEG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ISGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ISHR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ISLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_F2U, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_U2F, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UADD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UDIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMAD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMOD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMUL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USEQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USHR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SWITCH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CASE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DEFAULT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDSWITCH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_LAST, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, +}; diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index 40064ba8a9..23b6a83b9a 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -23,243 +23,23 @@ #ifndef R600_SHADER_H #define R600_SHADER_H -#include "r600_compiler.h" -#include "radeon.h" - -struct r600_shader_operand { - struct c_vector *vector; - unsigned sel; - unsigned chan; - unsigned neg; - unsigned abs; -}; - -struct r600_shader_vfetch { - struct list_head head; - unsigned cf_addr; - struct r600_shader_operand src[2]; - struct r600_shader_operand dst[4]; -}; - -struct r600_shader_inst { - unsigned is_op3; - unsigned opcode; - unsigned inst; - struct r600_shader_operand src[3]; - struct r600_shader_operand dst; - unsigned last; -}; - -struct r600_shader_alu { - struct list_head head; - unsigned nalu; - unsigned nliteral; - unsigned nconstant; - struct r600_shader_inst alu[5]; - u32 literal[4]; -}; - -struct r600_shader_node { - struct list_head head; - unsigned cf_id; /**< cf index (in dw) in byte code */ - unsigned cf_addr; /**< instructions index (in dw) in byte code */ - unsigned nslot; /**< number of slot (2 dw) needed by this node */ - unsigned nfetch; - struct c_node *node; /**< compiler node from which this node originate */ - struct list_head vfetch; /**< list of vfetch instructions */ - struct list_head alu; /**< list of alu instructions */ -}; +#include "r600_asm.h" struct r600_shader_io { - unsigned name; - unsigned gpr; - int sid; + unsigned name; + unsigned gpr; + int sid; }; struct r600_shader { - unsigned stack_size; /**< stack size needed by this shader */ - unsigned ngpr; /**< number of GPR needed by this shader */ - unsigned nconstant; /**< number of constants used by this shader */ - unsigned nresource; /**< number of resources used by this shader */ - unsigned noutput; - unsigned ninput; - unsigned nvector; - unsigned ncf; /**< total number of cf clauses */ - unsigned nslot; /**< total number of slots (2 dw) */ - unsigned flat_shade; /**< are we flat shading */ - struct list_head nodes; /**< list of node */ - struct r600_shader_io input[32]; - struct r600_shader_io output[32]; - /* TODO replace GPR by some better register allocator */ - struct c_vector **gpr; - unsigned ndw; /**< bytes code size in dw */ - u32 *bcode; /**< bytes code */ - enum pipe_format resource_format[160]; /**< format of resource */ - struct c_shader cshader; - boolean r6xx_compile; + unsigned processor_type; + struct r600_bc bc; + boolean flat_shade; + unsigned ninput; + unsigned noutput; + struct r600_shader_io input[32]; + struct r600_shader_io output[32]; + enum radeon_family family; }; -void r600_shader_cleanup(struct r600_shader *rshader); -int r600_shader_register(struct r600_shader *rshader); -int r600_shader_node(struct r600_shader *shader); -void r600_shader_node_place(struct r600_shader *rshader); -int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle, - struct r600_shader_operand *operand); -int r600_shader_vfetch_bytecode(struct r600_shader *rshader, - struct r600_shader_node *rnode, - struct r600_shader_vfetch *vfetch, - unsigned *cid); -int r600_shader_update(struct r600_shader *rshader, - enum pipe_format *resource_format); -int r600_shader_legalize(struct r600_shader *rshader); -int r600_cshader_legalize(struct c_shader *shader); - -int r700_shader_translate(struct r600_shader *rshader); - -int c_shader_from_tgsi(struct c_shader *shader, unsigned type, - const struct tgsi_token *tokens); -int r600_shader_register(struct r600_shader *rshader); -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, - INST_MUL_IEEE = 2, - INST_MAX = 3, - INST_MIN = 4, - INST_MAX_DX10 = 5, - INST_MIN_DX10 = 6, - INST_SETE = 7, - INST_SETGT = 8, - INST_SETGE = 9, - INST_SETNE = 10, - INST_SETE_DX10 = 11, - INST_SETGT_DX10 = 12, - INST_SETGE_DX10 = 13, - INST_SETNE_DX10 = 14, - INST_FRACT = 15, - INST_TRUNC = 16, - INST_CEIL = 17, - INST_RNDNE = 18, - INST_FLOOR = 19, - INST_MOVA = 20, - INST_MOVA_FLOOR = 21, - INST_MOVA_INT = 22, - INST_MOV = 23, - INST_NOP = 24, - INST_PRED_SETGT_UINT = 25, - INST_PRED_SETGE_UINT = 26, - INST_PRED_SETE = 27, - INST_PRED_SETGT = 28, - INST_PRED_SETGE = 29, - INST_PRED_SETNE = 30, - INST_PRED_SET_INV = 31, - INST_PRED_SET_POP = 32, - INST_PRED_SET_CLR = 33, - INST_PRED_SET_RESTORE = 34, - INST_PRED_SETE_PUSH = 35, - INST_PRED_SETGT_PUSH = 36, - INST_PRED_SETGE_PUSH = 37, - INST_PRED_SETNE_PUSH = 38, - INST_KILLE = 39, - INST_KILLGT = 40, - INST_KILLGE = 41, - INST_KILLNE = 42, - INST_AND_INT = 43, - INST_OR_INT = 44, - INST_XOR_INT = 45, - INST_NOT_INT = 46, - INST_ADD_INT = 47, - INST_SUB_INT = 48, - INST_MAX_INT = 49, - INST_MIN_INT = 50, - INST_MAX_UINT = 51, - INST_MIN_UINT = 52, - INST_SETE_INT = 53, - INST_SETGT_INT = 54, - INST_SETGE_INT = 55, - INST_SETNE_INT = 56, - INST_SETGT_UINT = 57, - INST_SETGE_UINT = 58, - INST_KILLGT_UINT = 59, - INST_KILLGE_UINT = 60, - INST_PRED_SETE_INT = 61, - INST_PRED_SETGT_INT = 62, - INST_PRED_SETGE_INT = 63, - INST_PRED_SETNE_INT = 64, - INST_KILLE_INT = 65, - INST_KILLGT_INT = 66, - INST_KILLGE_INT = 67, - INST_KILLNE_INT = 68, - INST_PRED_SETE_PUSH_INT = 69, - INST_PRED_SETGT_PUSH_INT = 70, - INST_PRED_SETGE_PUSH_INT = 71, - INST_PRED_SETNE_PUSH_INT = 72, - INST_PRED_SETLT_PUSH_INT = 73, - INST_PRED_SETLE_PUSH_INT = 74, - INST_DOT4 = 75, - INST_DOT4_IEEE = 76, - INST_CUBE = 77, - INST_MAX4 = 78, - INST_MOVA_GPR_INT = 79, - INST_EXP_IEEE = 80, - INST_LOG_CLAMPED = 81, - INST_LOG_IEEE = 82, - INST_RECIP_CLAMPED = 83, - INST_RECIP_FF = 84, - INST_RECIP_IEEE = 85, - INST_RECIPSQRT_CLAMPED = 86, - INST_RECIPSQRT_FF = 87, - INST_RECIPSQRT_IEEE = 88, - INST_SQRT_IEEE = 89, - INST_FLT_TO_INT = 90, - INST_INT_TO_FLT = 91, - INST_UINT_TO_FLT = 92, - INST_SIN = 93, - INST_COS = 94, - INST_ASHR_INT = 95, - INST_LSHR_INT = 96, - INST_LSHL_INT = 97, - INST_MULLO_INT = 98, - INST_MULHI_INT = 99, - INST_MULLO_UINT = 100, - INST_MULHI_UINT = 101, - INST_RECIP_INT = 102, - INST_RECIP_UINT = 103, - INST_FLT_TO_UINT = 104, - INST_MUL_LIT = 105, - INST_MUL_LIT_M2 = 106, - INST_MUL_LIT_M4 = 107, - INST_MUL_LIT_D2 = 108, - INST_MULADD = 109, - INST_MULADD_M2 = 110, - INST_MULADD_M4 = 111, - INST_MULADD_D2 = 112, - INST_MULADD_IEEE = 113, - INST_MULADD_IEEE_M2 = 114, - INST_MULADD_IEEE_M4 = 115, - INST_MULADD_IEEE_D2 = 116, - INST_CNDE = 117, - INST_CNDGT = 118, - INST_CNDGE = 119, - INST_CNDE_INT = 120, - INST_CNDGT_INT = 121, - INST_CNDGE_INT = 122, - INST_COUNT -}; - -struct r600_instruction_info { - enum r600_instruction instruction; - unsigned opcode; - unsigned is_trans; - unsigned is_op3; -}; - - #endif diff --git a/src/gallium/drivers/r600/r600_sq.h b/src/gallium/drivers/r600/r600_sq.h index 447ba98f00..4770ab0bf7 100644 --- a/src/gallium/drivers/r600/r600_sq.h +++ b/src/gallium/drivers/r600/r600_sq.h @@ -87,9 +87,9 @@ #define G_SQ_CF_WORD1_BARRIER(x) (((x) >> 31) & 0x1) #define C_SQ_CF_WORD1_BARRIER 0x7FFFFFFF #define P_SQ_CF_ALU_WORD0 -#define S_SQ_CF_ALU_WORD0_ALU_ADDR(x) (((x) & 0x3FFFFF) << 0) -#define G_SQ_CF_ALU_WORD0_ALU_ADDR(x) (((x) >> 0) & 0x3FFFFF) -#define C_SQ_CF_ALU_WORD0_ALU_ADDR 0xFFC00000 +#define S_SQ_CF_ALU_WORD0_ADDR(x) (((x) & 0x3FFFFF) << 0) +#define G_SQ_CF_ALU_WORD0_ADDR(x) (((x) >> 0) & 0x3FFFFF) +#define C_SQ_CF_ALU_WORD0_ADDR 0xFFC00000 #define S_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) & 0xF) << 22) #define G_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) >> 22) & 0xF) #define C_SQ_CF_ALU_WORD0_KCACHE_BANK0 0xFC3FFFFF @@ -109,15 +109,15 @@ #define S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) & 0xFF) << 10) #define G_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) >> 10) & 0xFF) #define C_SQ_CF_ALU_WORD1_KCACHE_ADDR1 0xFFFC03FF -#define S_SQ_CF_ALU_WORD1_ALU_COUNT(x) (((x) & 0x7F) << 18) -#define G_SQ_CF_ALU_WORD1_ALU_COUNT(x) (((x) >> 18) & 0x7F) -#define C_SQ_CF_ALU_WORD1_ALU_COUNT 0xFE03FFFF +#define S_SQ_CF_ALU_WORD1_COUNT(x) (((x) & 0x7F) << 18) +#define G_SQ_CF_ALU_WORD1_COUNT(x) (((x) >> 18) & 0x7F) +#define C_SQ_CF_ALU_WORD1_COUNT 0xFE03FFFF #define S_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) & 0x1) << 25) #define G_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) >> 25) & 0x1) #define C_SQ_CF_ALU_WORD1_USES_WATERFALL 0xFDFFFFFF -#define S_SQ_CF_ALU_WORD1_CF_ALU_INST(x) (((x) & 0xF) << 26) -#define G_SQ_CF_ALU_WORD1_CF_ALU_INST(x) (((x) >> 26) & 0xF) -#define C_SQ_CF_ALU_WORD1_CF_ALU_INST 0xC3FFFFFF +#define S_SQ_CF_ALU_WORD1_CF_INST(x) (((x) & 0xF) << 26) +#define G_SQ_CF_ALU_WORD1_CF_INST(x) (((x) >> 26) & 0xF) +#define C_SQ_CF_ALU_WORD1_CF_INST 0xC3FFFFFF #define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU 0x00000008 #define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE 0x00000009 #define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER 0x0000000A diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 4150f88785..84a13e4ef7 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -151,7 +151,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, static void *r600_create_fs_state(struct pipe_context *ctx, const struct pipe_shader_state *shader) { - return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_FS, shader->tokens); + return r600_pipe_shader_create(ctx, shader->tokens); } static void r600_bind_fs_state(struct pipe_context *ctx, void *state) @@ -164,7 +164,7 @@ static void r600_bind_fs_state(struct pipe_context *ctx, void *state) static void *r600_create_vs_state(struct pipe_context *ctx, const struct pipe_shader_state *shader) { - return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_VS, shader->tokens); + return r600_pipe_shader_create(ctx, shader->tokens); } static void r600_bind_vs_state(struct pipe_context *ctx, void *state) diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c new file mode 100644 index 0000000000..3532ba5b0c --- /dev/null +++ b/src/gallium/drivers/r600/r700_asm.c @@ -0,0 +1,70 @@ +/* + * Copyright 2010 Jerome Glisse + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "r600_asm.h" +#include "r600_context.h" +#include "util/u_memory.h" +#include "r700_sq.h" +#include +#include + +int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id) +{ + unsigned i; + + /* don't replace gpr by pv or ps for destination register */ + if (alu->is_op3) { + bc->bytecode[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); + bc->bytecode[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->inst) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } else { + bc->bytecode[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); + bc->bytecode[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(alu->dst.write) | + S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } + if (alu->last) { + for (i = 0; i < alu->nliteral; i++) { + bc->bytecode[id++] = alu->value[i]; + } + } + return 0; +} -- cgit v1.2.3