diff options
Diffstat (limited to 'src/mesa/shader')
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 79 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 102 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_ir.h | 4 |
3 files changed, 75 insertions, 110 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index a5f033d9123..780c9c1cfed 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -47,7 +47,7 @@ #include "slang_print.h" -static GLboolean UseHighLevelInstructions = GL_FALSE; +static GLboolean UseHighLevelInstructions = GL_TRUE; static slang_ir_node * _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper); @@ -602,42 +602,13 @@ new_break(slang_ir_node *beginNode) } -/** - * Child[0] is the condition. - * XXX we might re-design IR_IF so Children[1] is the "then" body and - * Children[0] is the "else" body. - */ static slang_ir_node * -new_if(slang_ir_node *cond) +new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart) { - slang_ir_node *n = new_node(IR_IF, NULL, NULL); + slang_ir_node *n = new_node(IR_IF, cond, ifPart); assert(cond); if (n) { - n->Children[0] = cond; - } - return n; -} - - -static slang_ir_node * -new_else(slang_ir_node *ifNode) -{ - slang_ir_node *n = new_node(IR_ELSE, NULL, NULL); - assert(ifNode); - if (n) { - n->BranchNode = ifNode; - } - return n; -} - - -static slang_ir_node * -new_endif(slang_ir_node *elseOrIfNode) -{ - slang_ir_node *n = new_node(IR_ENDIF, NULL, NULL); - assert(elseOrIfNode); - if (n) { - n->BranchNode = elseOrIfNode; + n->Children[2] = elsePart; } return n; } @@ -1445,8 +1416,8 @@ _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) * body code (child[1]) * ENDLOOP */ - slang_ir_node *beginLoop, *endLoop, *ifThen, *endif; - slang_ir_node *brk, *cond, *body, *tree; + slang_ir_node *beginLoop, *endLoop, *ifThen; + slang_ir_node *cond, *body, *tree; beginLoop = new_begin_loop(); @@ -1454,15 +1425,11 @@ _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) cond = new_node(IR_NOT, cond, NULL); cond = _slang_gen_cond(cond); - ifThen = new_if(cond); + ifThen = new_if(cond, + new_break(beginLoop), + NULL); tree = new_seq(beginLoop, ifThen); - brk = new_break(beginLoop); - tree = new_seq(tree, brk); - - endif = new_endif(ifThen); - tree = new_seq(tree, endif); - body = _slang_gen_operation(A, &oper->children[1]); if (body) tree = new_seq(tree, body); @@ -1702,7 +1669,7 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) /** * Generate IR tree for an if/then/else conditional using high-level - * IF/ELSE/ENDIF instructions + * IR_IF instruction. */ static slang_ir_node * _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) @@ -1720,29 +1687,19 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) * instruction. */ const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); - slang_ir_node *ifNode, *cond, *trueBody, *elseNode, *falseBody, *endifNode; - slang_ir_node *tree; + slang_ir_node *ifNode, *cond, *ifBody, *elseBody; cond = _slang_gen_operation(A, &oper->children[0]); cond = _slang_gen_cond(cond); - /*assert(cond->Store);*/ - ifNode = new_if(cond); - - trueBody = _slang_gen_operation(A, &oper->children[1]); - tree = new_seq(ifNode, trueBody); - - if (haveElseClause) { - elseNode = new_else(ifNode); - tree = new_seq(tree, elseNode); - - falseBody = _slang_gen_operation(A, &oper->children[2]); - tree = new_seq(tree, falseBody); - } + ifBody = _slang_gen_operation(A, &oper->children[1]); + if (haveElseClause) + elseBody = _slang_gen_operation(A, &oper->children[2]); + else + elseBody = NULL; - endifNode = new_endif(haveElseClause ? elseNode : ifNode); - tree = new_seq(tree, endifNode); + ifNode = new_if(cond, ifBody, elseBody); - return tree; + return ifNode; } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 3faacdd4cf8..82a8f0befb4 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -103,8 +103,6 @@ static slang_ir_info IrInfo[] = { { IR_CJUMP0, "IR_CJUMP0", OPCODE_NOP, 0, 0 }, { IR_CJUMP1, "IR_CJUMP1", OPCODE_NOP, 0, 0 }, { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 }, - { IR_ELSE, "IR_ELSE", OPCODE_NOP, 0, 0 }, - { IR_ENDIF, "IR_ENDIF", OPCODE_NOP, 0, 0 }, { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 }, { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 }, { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 }, @@ -232,11 +230,18 @@ storage_string(const slang_ir_storage *st) } +static void +spaces(int n) +{ + while (n-- > 0) { + printf(" "); + } +} + #define IND 0 void slang_print_ir(const slang_ir_node *n, int indent) { - int i; if (!n) return; #if !IND @@ -244,8 +249,7 @@ slang_print_ir(const slang_ir_node *n, int indent) #else printf("%3d:", indent); #endif - for (i = 0; i < indent; i++) - printf(" "); + spaces(indent); switch (n->Opcode) { case IR_SEQ: @@ -289,11 +293,14 @@ slang_print_ir(const slang_ir_node *n, int indent) case IR_IF: printf("IF \n"); slang_print_ir(n->Children[0], indent+3); - break; - case IR_ELSE: - printf("ELSE\n"); - break; - case IR_ENDIF: + spaces(indent); + printf("THEN\n"); + slang_print_ir(n->Children[1], indent+3); + if (n->Children[2]) { + spaces(indent); + printf("ELSE\n"); + slang_print_ir(n->Children[2], indent+3); + } printf("ENDIF\n"); break; @@ -1041,6 +1048,44 @@ emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } +static struct prog_instruction * +emit_if(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +{ + struct prog_instruction *ifInst; + GLuint ifInstLoc, elseInstLoc; + + emit(vt, n->Children[0], prog); /* the condition */ + ifInstLoc = prog->NumInstructions; + ifInst = new_instruction(prog, OPCODE_IF); + ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ + ifInst->DstReg.CondSwizzle = SWIZZLE_X; + + /* if body */ + emit(vt, n->Children[1], prog); + + if (n->Children[2]) { + /* else body */ + elseInstLoc = prog->NumInstructions; + (void) new_instruction(prog, OPCODE_ELSE); + ifInst = prog->Instructions + ifInstLoc; + ifInst->BranchTarget = prog->NumInstructions; + + emit(vt, n->Children[2], prog); + } + else { + ifInst = prog->Instructions + ifInstLoc; + ifInst->BranchTarget = prog->NumInstructions + 1; + } + + (void) new_instruction(prog, OPCODE_ENDIF); + if (n->Children[2]) { + struct prog_instruction *elseInst; + elseInst = prog->Instructions + elseInstLoc; + elseInst->BranchTarget = prog->NumInstructions; + } + return NULL; +} + /** * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term). @@ -1254,42 +1299,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) return emit_kill(prog); case IR_IF: - { - struct prog_instruction *inst; - emit(vt, n->Children[0], prog); /* the condition */ - inst = new_instruction(prog, OPCODE_IF); - inst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ - inst->DstReg.CondSwizzle = SWIZZLE_X; - n->InstLocation = prog->NumInstructions - 1; - return inst; - } - case IR_ELSE: - { - struct prog_instruction *inst, *ifInst; - n->InstLocation = prog->NumInstructions; - inst = new_instruction(prog, OPCODE_ELSE); - /* point IF's BranchTarget just after this instruction */ - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - ifInst = prog->Instructions + n->BranchNode->InstLocation; - assert(ifInst->Opcode == OPCODE_IF); - ifInst->BranchTarget = prog->NumInstructions; - return inst; - } - case IR_ENDIF: - { - struct prog_instruction *inst, *elseInst; - n->InstLocation = prog->NumInstructions; - inst = new_instruction(prog, OPCODE_ENDIF); - /* point ELSE's BranchTarget to just after this inst */ - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - elseInst = prog->Instructions + n->BranchNode->InstLocation; - assert(elseInst->Opcode == OPCODE_ELSE || - elseInst->Opcode == OPCODE_IF); - elseInst->BranchTarget = prog->NumInstructions; - return inst; - } + return emit_if(vt, n, prog); case IR_BEGIN_LOOP: { diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index df5fc067790..0f2ceb03c07 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -53,9 +53,7 @@ typedef enum IR_CJUMP1, /* conditional jump if one (or non-zero) */ IR_COND, /* conditional expression/predicate */ - IR_IF, /* high-level IF */ - IR_ELSE, /* high-level ELSE */ - IR_ENDIF, /* high-level ENDIF */ + IR_IF, /* high-level IF/then/else */ IR_BEGIN_SUB, /* begin subroutine */ IR_END_SUB, /* end subroutine */ |