diff options
author | Brian <brian@yutani.localnet.net> | 2007-01-20 09:27:40 -0700 |
---|---|---|
committer | Brian <brian@yutani.localnet.net> | 2007-01-20 09:27:40 -0700 |
commit | 5ae49cf3ed53fda6a904d7e90feef78495ae6903 (patch) | |
tree | 9314ccc16363edd6a4863788d864a60927dda6da /src/mesa/shader/slang | |
parent | a3e938b8da07e656775e88bb4b078429723689a2 (diff) |
Initial implementation of OPCODE_IF/ELSE/ENDIF instructions.
Diffstat (limited to 'src/mesa/shader/slang')
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 53 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 37 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_ir.h | 3 |
3 files changed, 92 insertions, 1 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 6923c00562..aba6813a8b 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1561,6 +1561,51 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) /** + * Use high-level IF/ELSE/ENDIF instructions + */ +static slang_ir_node * +_slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * eval expr (child[0]), updating condcodes + * branch if false to _else or _endif + * "true" code block + * if haveElseClause clause: + * jump "__endif" + * label "__else" + * "false" code block + * label "__endif" + */ + const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); + slang_ir_node *ifNode, *cond, *trueBody, *elseNode, *falseBody, *endifNode; + slang_ir_node *tree; + + cond = _slang_gen_operation(A, &oper->children[0]); + cond = _slang_gen_cond(cond); + /*assert(cond->Store);*/ + ifNode = new_node(IR_IF, cond, NULL); + + trueBody = _slang_gen_operation(A, &oper->children[1]); + tree = new_seq(ifNode, trueBody); + + if (haveElseClause) { + /* else clause */ + elseNode = new_node(IR_ELSE, NULL, NULL); + tree = new_seq(tree, elseNode); + + falseBody = _slang_gen_operation(A, &oper->children[2]); + tree = new_seq(tree, falseBody); + } + + endifNode = new_node(IR_ENDIF, NULL, NULL); + tree = new_seq(tree, endifNode); + + return tree; +} + + + +/** * Generate IR node for storage of a temporary of given size. */ static slang_ir_node * @@ -2314,7 +2359,13 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) case slang_oper_identifier: return _slang_gen_variable(A, oper); case slang_oper_if: - return _slang_gen_if(A, oper); + if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB) { + return _slang_gen_if(A, oper); + } + else { + /* XXX update tnl executor */ + return _slang_gen_if(A, oper); + } case slang_oper_field: return _slang_gen_field(A, oper); case slang_oper_subscript: diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 6c31bfc677..44fd3752e2 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -91,6 +91,9 @@ static slang_ir_info IrInfo[] = { { IR_JUMP, "IR_JUMP", 0, 0, 0 }, { IR_CJUMP0, "IR_CJUMP0", 0, 0, 0 }, { IR_CJUMP1, "IR_CJUMP1", 0, 0, 0 }, + { IR_IF, "IR_IF", 0, 0, 0 }, + { IR_ELSE, "IR_ELSE", 0, 0, 0 }, + { IR_ENDIF, "IR_ENDIF", 0, 0, 0 }, { IR_KILL, "IR_KILL", 0, 0, 0 }, { IR_COND, "IR_COND", 0, 0, 0 }, { IR_CALL, "IR_CALL", 0, 0, 0 }, @@ -271,6 +274,18 @@ slang_print_ir(const slang_ir_node *n, int indent) printf("CJUMP1 %s\n", n->Target); slang_print_ir(n->Children[0], indent+3); break; + + 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: + printf("ENDIF\n"); + break; + case IR_VAR: printf("VAR %s%s at %s store %p\n", (char *) n->Var->a_name, swizzle_string(n->Store->Swizzle), @@ -862,6 +877,28 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_KILL: 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; + return inst; + } + case IR_ELSE: + { + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_ELSE); + return inst; + } + case IR_ENDIF: + { + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_ENDIF); + return inst; + } + default: _mesa_problem(NULL, "Unexpected IR opcode in emit()\n"); abort(); diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index 4072c70f90..e5a0fa8eb5 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -51,6 +51,9 @@ typedef enum IR_CJUMP0, /* conditional jump if zero */ IR_CJUMP1, /* conditional jump if one (or non-zero) */ IR_COND, /* conditional expression */ + IR_IF, /* high-level IF */ + IR_ELSE, /* high-level ELSE */ + IR_ENDIF, /* high-level ENDIF */ IR_CALL, /* call subroutine */ IR_MOVE, IR_ADD, |