From 204336451678ba8710756111e6cf4867d6adb40e Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Feb 2007 20:45:43 -0700 Subject: redo IR_IF node, removing IR_ELSE, IR_ENDIF --- src/mesa/shader/slang/slang_emit.c | 102 ++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 46 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') 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: { -- cgit v1.2.3 From 5f7d4668c4b7de1c0d2269809d30aef6d0a089e9 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Feb 2007 21:33:29 -0700 Subject: replace IR_BEGIN_LOOP/IR_END_LOOP with IR_LOOP --- src/mesa/shader/slang/slang_codegen.c | 79 ++++++++++++++++------------------ src/mesa/shader/slang/slang_emit.c | 35 ++++++++------- src/mesa/shader/slang/slang_ir.h | 3 +- src/mesa/shader/slang/slang_typeinfo.h | 1 + 4 files changed, 58 insertions(+), 60 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 88d61a5a681..a4e2935ea84 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -490,10 +490,12 @@ static void _slang_free_ir_tree(slang_ir_node *n) { #if 0 + GLuint i; if (!n) return; - _slang_free_ir_tree(n->Children[0]); - _slang_free_ir_tree(n->Children[1]); + for (i = 0; i < 3; i++) + _slang_free_ir_tree(n->Children[i]); + /* Do not free n->BranchNode since it's a child elsewhere */ free(n); #endif } @@ -537,9 +539,10 @@ new_node0(slang_ir_opcode op) static slang_ir_node * new_seq(slang_ir_node *left, slang_ir_node *right) { - /* XXX if either left or right is null, just return pointer to other?? */ - assert(left); - assert(right); + if (!left) + return right; + if (!right) + return left; return new_node2(IR_SEQ, left, right); } @@ -592,32 +595,20 @@ new_jump(slang_atom target) static slang_ir_node * -new_begin_loop(void) -{ - slang_ir_node *n = new_node0(IR_BEGIN_LOOP); - return n; -} - - -static slang_ir_node * -new_end_loop(slang_ir_node *beginNode) +new_loop(slang_ir_node *body) { - slang_ir_node *n = new_node0(IR_END_LOOP); - assert(beginNode); - if (n) { - n->BranchNode = beginNode; - } - return n; + return new_node1(IR_LOOP, body); } static slang_ir_node * -new_break(slang_ir_node *beginNode) +new_break(slang_ir_node *loopNode) { slang_ir_node *n = new_node0(IR_BREAK); - assert(beginNode); + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); if (n) { - n->BranchNode = beginNode; + n->BranchNode = loopNode; } return n; } @@ -1415,43 +1406,43 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) /** - * Generate IR tree for a while-loop using high-level BGNLOOP/ENDLOOP, - * IF/ENDIF instructions. + * Generate IR tree for a while-loop using high-level LOOP, IF instructions. */ static slang_ir_node * _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) { + slang_ir_node *prevLoop; /* - * BGNLOOP + * LOOP: * eval expr (child[0]), updating condcodes - * IF !expr THEN + * IF !expr: * BRK - * ENDIF * body code (child[1]) - * ENDLOOP */ - slang_ir_node *beginLoop, *endLoop, *ifThen; - slang_ir_node *cond, *body, *tree; + slang_ir_node *ifThen, *cond, *body, *loop; - beginLoop = new_begin_loop(); + loop = new_loop(NULL); + + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; cond = _slang_gen_operation(A, &oper->children[0]); cond = new_node1(IR_NOT, cond); cond = _slang_gen_cond(cond); ifThen = new_if(cond, - new_break(beginLoop), + new_break(A->CurLoop), NULL); - tree = new_seq(beginLoop, ifThen); body = _slang_gen_operation(A, &oper->children[1]); - if (body) - tree = new_seq(tree, body); - endLoop = new_end_loop(beginLoop); - tree = new_seq(tree, endLoop); + loop->Children[0] = new_seq(ifThen, body); - return tree; + + A->CurLoop = prevLoop; /* pop loop, restore prev */ + + return loop; } @@ -2433,11 +2424,15 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) else return _slang_gen_for(A, oper); case slang_oper_break: - if (!A->CurLoopBreak) { + if (!A->CurLoop && !A->CurLoopBreak) { RETURN_ERROR("'break' not in loop", 0); } - /* XXX emit IR_BREAK instruction */ - return new_jump(A->CurLoopBreak); + if (UseHighLevelInstructions) { + return new_break(A->CurLoop); + } + else { + return new_jump(A->CurLoopBreak); + } case slang_oper_continue: if (!A->CurLoopCont) { RETURN_ERROR("'continue' not in loop", 0); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 82a8f0befb4..c18f1e364ce 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -317,11 +317,11 @@ slang_print_ir(const slang_ir_node *n, int indent) printf("CALL\n"); break; - case IR_BEGIN_LOOP: - printf("BEGIN_LOOP\n"); - break; - case IR_END_LOOP: - printf("END_LOOP\n"); + case IR_LOOP: + printf("LOOP\n"); + slang_print_ir(n->Children[0], indent+3); + spaces(indent); + printf("ENDLOOP\n"); break; case IR_CONT: printf("CONT\n"); @@ -1301,23 +1301,22 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_IF: return emit_if(vt, n, prog); - case IR_BEGIN_LOOP: + case IR_LOOP: { + struct prog_instruction *beginInst; + /* save location of this instruction, used by OPCODE_ENDLOOP */ n->InstLocation = prog->NumInstructions; (void) new_instruction(prog, OPCODE_BGNLOOP); - } - break; - case IR_END_LOOP: - { - struct prog_instruction *inst, *beginInst; + + /* body */ + emit(vt, n->Children[0], prog); + inst = new_instruction(prog, OPCODE_ENDLOOP); - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); /* The instruction BranchTarget points to top of loop */ - inst->BranchTarget = n->BranchNode->InstLocation; - /* Update BEGIN_LOOP's BranchTarget to point to this instruction */ - beginInst = prog->Instructions + n->BranchNode->InstLocation; + inst->BranchTarget = n->InstLocation; + /* Update BGNLOOP's BranchTarget to point to this instruction */ + beginInst = prog->Instructions + n->InstLocation; beginInst->BranchTarget = prog->NumInstructions - 1; return inst; } @@ -1336,6 +1335,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) inst->BranchTarget = n->BranchNode->InstLocation; return inst; } + case IR_BEGIN_SUB: return new_instruction(prog, OPCODE_BGNSUB); case IR_END_SUB: @@ -1343,6 +1343,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_RETURN: return new_instruction(prog, OPCODE_RET); + case IR_NOP: + return NULL; + 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 0f2ceb03c07..a7c858c69f7 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -60,8 +60,7 @@ typedef enum IR_RETURN, /* return from subroutine */ IR_CALL, /* call subroutine */ - IR_BEGIN_LOOP,/* begin loop */ - IR_END_LOOP, /* end loop */ + IR_LOOP, /* high-level loop-begin / loop-end */ IR_CONT, /* continue loop */ IR_BREAK, /* break loop */ diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index 6e27079ff89..d23bb6be146 100644 --- a/src/mesa/shader/slang/slang_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -63,6 +63,7 @@ typedef struct slang_assemble_ctx_ struct slang_function_ *CurFunction; slang_atom CurLoopBreak; slang_atom CurLoopCont; + struct slang_ir_node_ *CurLoop; } slang_assemble_ctx; -- cgit v1.2.3 From f22ed0986a743e033d827c78371612c7115ff913 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Feb 2007 22:31:19 -0700 Subject: Implement CONT, improve BRK. IR_LOOP's BranchNode ptr is the head of a linked list of CONT and BRK nodes. After emitting loop, walk over the linked list, filling in the CONT/BRK instruction's BranchTarget field (location of the ENDLOOP instruction, or one past). --- src/mesa/shader/prog_print.c | 10 ++++++-- src/mesa/shader/slang/slang_codegen.c | 29 ++++++++++++++++++--- src/mesa/shader/slang/slang_emit.c | 47 ++++++++++++++++++++++++++--------- src/mesa/swrast/s_fragprog.c | 6 +++++ 4 files changed, 74 insertions(+), 18 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 3d4a474b052..6c303de9b5a 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -338,8 +338,14 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: - /* XXX just like BRA */ - _mesa_printf("BRK (%s%s) (for loop beginning at %d)", + _mesa_printf("BRK (%s%s) (goto %d)", + condcode_string(inst->DstReg.CondMask), + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); + print_comment(inst); + break; + case OPCODE_CONT: + _mesa_printf("CONT (%s%s) (goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index a4e2935ea84..42c1f0897eb 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -608,7 +608,24 @@ new_break(slang_ir_node *loopNode) assert(loopNode); assert(loopNode->Opcode == IR_LOOP); if (n) { - n->BranchNode = loopNode; + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; + } + return n; +} + + +static slang_ir_node * +new_cont(slang_ir_node *loopNode) +{ + slang_ir_node *n = new_node0(IR_CONT); + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + if (n) { + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; } return n; } @@ -2434,11 +2451,15 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return new_jump(A->CurLoopBreak); } case slang_oper_continue: - if (!A->CurLoopCont) { + if (!A->CurLoop && !A->CurLoopCont) { RETURN_ERROR("'continue' not in loop", 0); } - /* XXX emit IR_CONT instruction */ - return new_jump(A->CurLoopCont); + if (UseHighLevelInstructions) { + return new_cont(A->CurLoop); + } + else { + return new_jump(A->CurLoopCont); + } case slang_oper_discard: return new_node0(IR_KILL); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index c18f1e364ce..2d5a7cf6f9d 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1303,7 +1303,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_LOOP: { - struct prog_instruction *beginInst; + struct prog_instruction *beginInst, *endInst; + GLuint endInstLoc; + slang_ir_node *p; /* save location of this instruction, used by OPCODE_ENDLOOP */ n->InstLocation = prog->NumInstructions; @@ -1312,27 +1314,48 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /* body */ emit(vt, n->Children[0], prog); - inst = new_instruction(prog, OPCODE_ENDLOOP); - /* The instruction BranchTarget points to top of loop */ - inst->BranchTarget = n->InstLocation; + endInstLoc = prog->NumInstructions; + endInst = new_instruction(prog, OPCODE_ENDLOOP); + /* The ENDLOOP's BranchTarget points to top of loop */ + endInst->BranchTarget = n->InstLocation; /* Update BGNLOOP's BranchTarget to point to this instruction */ beginInst = prog->Instructions + n->InstLocation; beginInst->BranchTarget = prog->NumInstructions - 1; - return inst; + + /* Done emitting loop code. Now walk over the loop's linked list + * of BREAK and CONT nodes, filling in their BranchTarget fields. + */ + for (p = n->BranchNode; p; p = p->BranchNode) { + if (p->Opcode == IR_BREAK) { + struct prog_instruction *brkInst + = prog->Instructions + p->InstLocation; + assert(brkInst->Opcode == OPCODE_BRK); + brkInst->BranchTarget = endInstLoc + 1; + } + else { + assert(p->Opcode == IR_CONT); + struct prog_instruction *contInst + = prog->Instructions + p->InstLocation; + assert(contInst->Opcode == OPCODE_CONT); + contInst->BranchTarget = endInstLoc; + } + } + return NULL; } case IR_CONT: - return new_instruction(prog, OPCODE_CONT); + { + struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; + inst = new_instruction(prog, OPCODE_CONT); + inst->DstReg.CondMask = COND_TR; /* always true */ + return inst; + } case IR_BREAK: { struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_BRK); inst->DstReg.CondMask = COND_TR; /* always true */ - /* This instruction's branch target is top of loop, not bottom of - * loop because we don't know where it is yet! - */ - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - inst->BranchTarget = n->BranchNode->InstLocation; return inst; } diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 12c8aee6ea0..63974b30f20 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -704,6 +704,7 @@ execute_program( GLcontext *ctx, break; case OPCODE_BRK: /* break out of loop */ { +#if 0 /* The location of the ENDLOOP instruction is saved in the * BGNLOOP instruction. Get that instruction and jump to * its BranchTarget + 1. @@ -714,6 +715,9 @@ execute_program( GLcontext *ctx, ASSERT(loopBeginInst->BranchTarget >= 0); /* we'll add one at bottom of for-loop */ pc = loopBeginInst->BranchTarget; +#else + pc = inst->BranchTarget - 1; +#endif } break; case OPCODE_CAL: /* Call subroutine */ @@ -747,6 +751,8 @@ execute_program( GLcontext *ctx, } break; case OPCODE_CONT: /* continue loop */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ + pc = inst->BranchTarget - 1; break; case OPCODE_COS: { -- cgit v1.2.3 From 4aa487e7968d015af4fe729f697105448fcb843f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 7 Feb 2007 15:12:13 -0700 Subject: Use IR_LOOP to represent do-while and for-loops. Also, start moving high vs. low-level instruction selection into slang_emit.c --- src/mesa/shader/slang/slang_codegen.c | 110 ++++++++++++++++++++-------------- src/mesa/shader/slang/slang_emit.c | 82 +++++++++++++++---------- src/mesa/shader/slang/slang_ir.h | 7 ++- src/mesa/shader/slang/slang_link.c | 2 +- src/mesa/swrast/s_fragprog.c | 12 ++-- 5 files changed, 128 insertions(+), 85 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 42c1f0897eb..14870f57ae8 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1423,7 +1423,7 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) /** - * Generate IR tree for a while-loop using high-level LOOP, IF instructions. + * Generate loop code using high-level IR_LOOP instruction */ static slang_ir_node * _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) @@ -1509,6 +1509,46 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) } +/** + * Generate IR tree for a do-while loop using high-level LOOP, IF instructions. + */ +static slang_ir_node * +_slang_gen_hl_do(slang_assemble_ctx * A, const slang_operation *oper) +{ + slang_ir_node *prevLoop; + /* + * LOOP: + * body code (child[0]) + * eval expr (child[1]), updating condcodes + * IF !expr: + * BRK + */ + slang_ir_node *ifThen, *cond, *body, *loop; + + loop = new_loop(NULL); + + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; + + body = _slang_gen_operation(A, &oper->children[0]); + + cond = _slang_gen_operation(A, &oper->children[1]); + cond = new_node1(IR_NOT, cond); + cond = _slang_gen_cond(cond); + + ifThen = new_if(cond, + new_break(A->CurLoop), + NULL); + + loop->Children[0] = new_seq(body, ifThen); + + A->CurLoop = prevLoop; /* pop loop, restore prev */ + + return loop; +} + + /** * Generate IR tree for a for-loop. */ @@ -1573,69 +1613,48 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) /** - * Generate IR tree for a for-loop, using high-level BGNLOOP/ENDLOOP and - * IF/ENDIF instructions. - * - * XXX note done yet! + * Generate for-loop using high-level IR_LOOP instruction. */ static slang_ir_node * _slang_gen_hl_for(slang_assemble_ctx * A, const slang_operation *oper) { + slang_ir_node *prevLoop; /* - * init code (child[0]) - * BGNLOOP + * init (child[0]) + * LOOP: * eval expr (child[1]), updating condcodes - * IF !expr THEN + * IF !expr: * BRK - * ENDIF - * code body (child[3]) - * label "__continueFor" // jump here for "continue" - * incr code (child[2]) - * ENDLOOP + * body code (child[3]) + * incr code (child[2]) // XXX continue here */ - slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startFor"); - slang_atom contAtom = slang_atom_pool_gen(A->atoms, "__continueFor"); - slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endFor"); - slang_ir_node *init, *startLab, *cond, *bra, *body, *contLab; - slang_ir_node *incr, *jump, *endLab, *tree; - slang_atom prevLoopBreak = A->CurLoopBreak; - slang_atom prevLoopCont = A->CurLoopCont; - - /* Push this loop */ - A->CurLoopBreak = endAtom; - A->CurLoopCont = contAtom; + slang_ir_node *init, *ifThen, *cond, *body, *loop, *incr; init = _slang_gen_operation(A, &oper->children[0]); - startLab = new_label(startAtom); - tree = new_seq(init, startLab); + loop = new_loop(NULL); + + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; cond = _slang_gen_operation(A, &oper->children[1]); + cond = new_node1(IR_NOT, cond); cond = _slang_gen_cond(cond); - tree = new_seq(tree, cond); - bra = new_cjump(endAtom, 0); - tree = new_seq(tree, bra); + ifThen = new_if(cond, + new_break(A->CurLoop), + NULL); body = _slang_gen_operation(A, &oper->children[3]); - tree = new_seq(tree, body); - - contLab = new_label(contAtom); - tree = new_seq(tree, contLab); incr = _slang_gen_operation(A, &oper->children[2]); - tree = new_seq(tree, incr); - - jump = new_jump(startAtom); - tree = new_seq(tree, jump); - endLab = new_label(endAtom); - tree = new_seq(tree, endLab); + loop->Children[0] = new_seq(ifThen, + new_seq(body,incr)); - /* Pop this loop */ - A->CurLoopBreak = prevLoopBreak; - A->CurLoopCont = prevLoopCont; + A->CurLoop = prevLoop; /* pop loop, restore prev */ - return tree; + return new_seq(init, loop); } @@ -2434,7 +2453,10 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) else return _slang_gen_while(A, oper); case slang_oper_do: - return _slang_gen_do(A, oper); + if (UseHighLevelInstructions) + return _slang_gen_hl_do(A, oper); + else + return _slang_gen_do(A, oper); case slang_oper_for: if (UseHighLevelInstructions) return _slang_gen_hl_for(A, oper); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 2d5a7cf6f9d..29588379a2f 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -43,6 +43,9 @@ #define ANNOTATE 1 +static GLboolean EmitHighLevelInstructions = GL_FALSE; + + /** * Assembly and IR info */ @@ -1304,57 +1307,72 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_LOOP: { struct prog_instruction *beginInst, *endInst; - GLuint endInstLoc; - slang_ir_node *p; + GLuint beginInstLoc, endInstLoc; + slang_ir_node *ir; - /* save location of this instruction, used by OPCODE_ENDLOOP */ - n->InstLocation = prog->NumInstructions; - (void) new_instruction(prog, OPCODE_BGNLOOP); + /* emit OPCODE_BGNLOOP */ + beginInstLoc = prog->NumInstructions; + if (EmitHighLevelInstructions) { + (void) new_instruction(prog, OPCODE_BGNLOOP); + } /* body */ emit(vt, n->Children[0], prog); endInstLoc = prog->NumInstructions; - endInst = new_instruction(prog, OPCODE_ENDLOOP); - /* The ENDLOOP's BranchTarget points to top of loop */ - endInst->BranchTarget = n->InstLocation; - /* Update BGNLOOP's BranchTarget to point to this instruction */ - beginInst = prog->Instructions + n->InstLocation; - beginInst->BranchTarget = prog->NumInstructions - 1; + if (EmitHighLevelInstructions) { + /* emit OPCODE_ENDLOOP */ + endInst = new_instruction(prog, OPCODE_ENDLOOP); + } + else { + /* emit unconditional BRA-nch */ + endInst = new_instruction(prog, OPCODE_BRA); + endInst->DstReg.CondMask = COND_TR; /* always true */ + } + /* end instruction's BranchTarget points to top of loop */ + endInst->BranchTarget = beginInstLoc; + + if (EmitHighLevelInstructions) { + /* BGNLOOP's BranchTarget points to the ENDLOOP inst */ + beginInst = prog->Instructions + beginInstLoc; + beginInst->BranchTarget = prog->NumInstructions - 1; + } /* Done emitting loop code. Now walk over the loop's linked list - * of BREAK and CONT nodes, filling in their BranchTarget fields. + * of BREAK and CONT nodes, filling in their BranchTarget fields + * (which will point to the ENDLOOP or ENDLOOP+1 instructions). */ - for (p = n->BranchNode; p; p = p->BranchNode) { - if (p->Opcode == IR_BREAK) { - struct prog_instruction *brkInst - = prog->Instructions + p->InstLocation; - assert(brkInst->Opcode == OPCODE_BRK); - brkInst->BranchTarget = endInstLoc + 1; + for (ir = n->BranchNode; ir; ir = ir->BranchNode) { + struct prog_instruction *inst + = prog->Instructions + ir->InstLocation; + if (ir->Opcode == IR_BREAK) { + assert(inst->Opcode == OPCODE_BRK || + inst->Opcode == OPCODE_BRA); + inst->BranchTarget = endInstLoc + 1; } else { - assert(p->Opcode == IR_CONT); - struct prog_instruction *contInst - = prog->Instructions + p->InstLocation; - assert(contInst->Opcode == OPCODE_CONT); - contInst->BranchTarget = endInstLoc; + assert(ir->Opcode == IR_CONT); + assert(inst->Opcode == OPCODE_CONT || + inst->Opcode == OPCODE_BRA); + inst->BranchTarget = endInstLoc; } } return NULL; } - case IR_CONT: - { - struct prog_instruction *inst; - n->InstLocation = prog->NumInstructions; - inst = new_instruction(prog, OPCODE_CONT); - inst->DstReg.CondMask = COND_TR; /* always true */ - return inst; - } case IR_BREAK: + /* fall-through */ + case IR_CONT: { + gl_inst_opcode opcode; struct prog_instruction *inst; n->InstLocation = prog->NumInstructions; - inst = new_instruction(prog, OPCODE_BRK); + if (EmitHighLevelInstructions) { + opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; + } + else { + opcode = OPCODE_BRA; + } + inst = new_instruction(prog, opcode); inst->DstReg.CondMask = COND_TR; /* always true */ return inst; } diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index a7c858c69f7..0c827d9cd8c 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -39,7 +39,7 @@ /** - * Intermediate Representation opcode + * Intermediate Representation opcodes */ typedef enum { @@ -64,6 +64,11 @@ typedef enum IR_CONT, /* continue loop */ IR_BREAK, /* break loop */ + IR_BREAK_IF_TRUE, + IR_BREAK_IF_FALSE, + IR_CONT_IF_TRUE, + IR_CONT_IF_FALSE, + IR_MOVE, IR_ADD, IR_SUB, diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 017cf6078cb..b1d355ff802 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -298,7 +298,7 @@ _slang_resolve_branches(struct gl_program *prog) for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; - if (inst->Opcode == OPCODE_BRA) { + if (inst->Opcode == OPCODE_BRA && inst->BranchTarget < 0) { for (j = 0; j < numTargets; j++) { if (!strcmp(inst->Comment, targets[j].Name)) { inst->BranchTarget = targets[j].Pos; diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 403a03aa32a..ace10a9222c 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -675,9 +675,10 @@ execute_program( GLcontext *ctx, } } break; - case OPCODE_BGNLOOP: /* begin loop */ + case OPCODE_BGNLOOP: + /* no-op */ break; - case OPCODE_ENDLOOP: /* end loop */ + case OPCODE_ENDLOOP: /* subtract 1 here since pc is incremented by for(pc) loop */ pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ break; @@ -695,10 +696,7 @@ execute_program( GLcontext *ctx, test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { /* take branch */ - pc = inst->BranchTarget; - /* - printf("Take branch to %u\n", pc); - */ + pc = inst->BranchTarget - 1; } } break; @@ -721,7 +719,7 @@ execute_program( GLcontext *ctx, return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ } machine->CallStack[machine->StackDepth++] = pc + 1; - pc = inst->BranchTarget; + pc = inst->BranchTarget; /* XXX - 1 ??? */ } } break; -- cgit v1.2.3 From b35b4566c2d3bbf21c8fd955912f4c3c671f2bb9 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 7 Feb 2007 16:11:00 -0700 Subject: high vs. low level if/then/else code emit --- src/mesa/shader/slang/slang_emit.c | 189 ++++++++++++++++++++++--------------- 1 file changed, 112 insertions(+), 77 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 29588379a2f..6e2394f2656 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -43,7 +43,7 @@ #define ANNOTATE 1 -static GLboolean EmitHighLevelInstructions = GL_FALSE; +static GLboolean EmitHighLevelInstructions = GL_TRUE; /** @@ -523,9 +523,9 @@ storage_annotation(const slang_ir_node *n, const struct gl_program *prog) if (st->Index >= 0) { const GLfloat *val = prog->Parameters->ParameterValues[st->Index]; if (st->Swizzle == SWIZZLE_NOOP) - sprintf(s, "{%f, %f, %f, %f}", val[0], val[1], val[2], val[3]); + sprintf(s, "{%g, %g, %g, %g}", val[0], val[1], val[2], val[3]); else { - sprintf(s, "%f", val[GET_SWZ(st->Swizzle, 0)]); + sprintf(s, "%g", val[GET_SWZ(st->Swizzle, 0)]); } } break; @@ -1059,28 +1059,50 @@ emit_if(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) 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 (EmitHighLevelInstructions) { + ifInst = new_instruction(prog, OPCODE_IF); + ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ + ifInst->DstReg.CondSwizzle = SWIZZLE_X; + } + else { + /* conditional jump to else, or endif */ + ifInst = new_instruction(prog, OPCODE_BRA); + ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */ + ifInst->DstReg.CondSwizzle = SWIZZLE_X; + ifInst->Comment = _mesa_strdup("if zero"); + } /* if body */ emit(vt, n->Children[1], prog); if (n->Children[2]) { - /* else body */ + /* have else body */ elseInstLoc = prog->NumInstructions; - (void) new_instruction(prog, OPCODE_ELSE); + if (EmitHighLevelInstructions) { + (void) new_instruction(prog, OPCODE_ELSE); + } + else { + /* jump to endif instruction */ + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_BRA); + inst->Comment = _mesa_strdup("else"); + inst->DstReg.CondMask = COND_TR; /* always branch */ + } ifInst = prog->Instructions + ifInstLoc; ifInst->BranchTarget = prog->NumInstructions; emit(vt, n->Children[2], prog); } else { + /* no else body */ ifInst = prog->Instructions + ifInstLoc; ifInst->BranchTarget = prog->NumInstructions + 1; } - (void) new_instruction(prog, OPCODE_ENDIF); + if (EmitHighLevelInstructions) { + (void) new_instruction(prog, OPCODE_ENDIF); + } + if (n->Children[2]) { struct prog_instruction *elseInst; elseInst = prog->Instructions + elseInstLoc; @@ -1090,6 +1112,85 @@ emit_if(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } +static struct prog_instruction * +emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +{ + struct prog_instruction *beginInst, *endInst; + GLuint beginInstLoc, endInstLoc; + slang_ir_node *ir; + + /* emit OPCODE_BGNLOOP */ + beginInstLoc = prog->NumInstructions; + if (EmitHighLevelInstructions) { + (void) new_instruction(prog, OPCODE_BGNLOOP); + } + + /* body */ + emit(vt, n->Children[0], prog); + + endInstLoc = prog->NumInstructions; + if (EmitHighLevelInstructions) { + /* emit OPCODE_ENDLOOP */ + endInst = new_instruction(prog, OPCODE_ENDLOOP); + } + else { + /* emit unconditional BRA-nch */ + endInst = new_instruction(prog, OPCODE_BRA); + endInst->DstReg.CondMask = COND_TR; /* always true */ + } + /* end instruction's BranchTarget points to top of loop */ + endInst->BranchTarget = beginInstLoc; + + if (EmitHighLevelInstructions) { + /* BGNLOOP's BranchTarget points to the ENDLOOP inst */ + beginInst = prog->Instructions + beginInstLoc; + beginInst->BranchTarget = prog->NumInstructions - 1; + } + + /* Done emitting loop code. Now walk over the loop's linked list + * of BREAK and CONT nodes, filling in their BranchTarget fields + * (which will point to the ENDLOOP or ENDLOOP+1 instructions). + */ + for (ir = n->BranchNode; ir; ir = ir->BranchNode) { + struct prog_instruction *inst = prog->Instructions + ir->InstLocation; + if (ir->Opcode == IR_BREAK) { + assert(inst->Opcode == OPCODE_BRK || + inst->Opcode == OPCODE_BRA); + inst->BranchTarget = endInstLoc + 1; + } + else { + assert(ir->Opcode == IR_CONT); + assert(inst->Opcode == OPCODE_CONT || + inst->Opcode == OPCODE_BRA); + /* XXX goto top of loop instead! */ + inst->BranchTarget = endInstLoc; + } + } + return NULL; +} + + +/** + * Emit code for IR_CONT or IR_BREAK. + */ +static struct prog_instruction * +emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +{ + gl_inst_opcode opcode; + struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; + if (EmitHighLevelInstructions) { + opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; + } + else { + opcode = OPCODE_BRA; + } + inst = new_instruction(prog, opcode); + inst->DstReg.CondMask = COND_TR; /* always true */ + return inst; +} + + /** * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term). * Ex: fix_swizzle("zyNN") -> "zyyy" @@ -1305,77 +1406,11 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) return emit_if(vt, n, prog); case IR_LOOP: - { - struct prog_instruction *beginInst, *endInst; - GLuint beginInstLoc, endInstLoc; - slang_ir_node *ir; - - /* emit OPCODE_BGNLOOP */ - beginInstLoc = prog->NumInstructions; - if (EmitHighLevelInstructions) { - (void) new_instruction(prog, OPCODE_BGNLOOP); - } - - /* body */ - emit(vt, n->Children[0], prog); - - endInstLoc = prog->NumInstructions; - if (EmitHighLevelInstructions) { - /* emit OPCODE_ENDLOOP */ - endInst = new_instruction(prog, OPCODE_ENDLOOP); - } - else { - /* emit unconditional BRA-nch */ - endInst = new_instruction(prog, OPCODE_BRA); - endInst->DstReg.CondMask = COND_TR; /* always true */ - } - /* end instruction's BranchTarget points to top of loop */ - endInst->BranchTarget = beginInstLoc; - - if (EmitHighLevelInstructions) { - /* BGNLOOP's BranchTarget points to the ENDLOOP inst */ - beginInst = prog->Instructions + beginInstLoc; - beginInst->BranchTarget = prog->NumInstructions - 1; - } - - /* Done emitting loop code. Now walk over the loop's linked list - * of BREAK and CONT nodes, filling in their BranchTarget fields - * (which will point to the ENDLOOP or ENDLOOP+1 instructions). - */ - for (ir = n->BranchNode; ir; ir = ir->BranchNode) { - struct prog_instruction *inst - = prog->Instructions + ir->InstLocation; - if (ir->Opcode == IR_BREAK) { - assert(inst->Opcode == OPCODE_BRK || - inst->Opcode == OPCODE_BRA); - inst->BranchTarget = endInstLoc + 1; - } - else { - assert(ir->Opcode == IR_CONT); - assert(inst->Opcode == OPCODE_CONT || - inst->Opcode == OPCODE_BRA); - inst->BranchTarget = endInstLoc; - } - } - return NULL; - } + return emit_loop(vt, n, prog); case IR_BREAK: /* fall-through */ case IR_CONT: - { - gl_inst_opcode opcode; - struct prog_instruction *inst; - n->InstLocation = prog->NumInstructions; - if (EmitHighLevelInstructions) { - opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; - } - else { - opcode = OPCODE_BRA; - } - inst = new_instruction(prog, opcode); - inst->DstReg.CondMask = COND_TR; /* always true */ - return inst; - } + return emit_cont_break(vt, n, prog); case IR_BEGIN_SUB: return new_instruction(prog, OPCODE_BGNSUB); -- cgit v1.2.3 From b768c485474baefdde63098776e9d32c17b859ab Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 8 Feb 2007 13:23:17 -0700 Subject: Use conditional break in for/do/while loops. --- src/mesa/shader/slang/slang_codegen.c | 106 +++++++++++++++------------------- src/mesa/shader/slang/slang_emit.c | 44 +++++++++++++- 2 files changed, 88 insertions(+), 62 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index bd7b30cd13a..6671f31c478 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -616,6 +616,21 @@ new_break(slang_ir_node *loopNode) } +static slang_ir_node * +new_break_if_false(slang_ir_node *loopNode, slang_ir_node *cond) +{ + slang_ir_node *n = new_node1(IR_BREAK_IF_FALSE, cond); + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + if (n) { + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; + } + return n; +} + + static slang_ir_node * new_cont(slang_ir_node *loopNode) { @@ -631,6 +646,14 @@ new_cont(slang_ir_node *loopNode) } +static slang_ir_node * +new_cond(slang_ir_node *n) +{ + slang_ir_node *c = new_node1(IR_COND, n); + return c; +} + + static slang_ir_node * new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart) { @@ -1290,14 +1313,6 @@ _slang_is_noop(const slang_operation *oper) } -static slang_ir_node * -_slang_gen_cond(slang_ir_node *n) -{ - slang_ir_node *c = new_node1(IR_COND, n); - return c; -} - - static void print_funcs(struct slang_function_scope_ *scope, const char *name) { @@ -1381,12 +1396,10 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) slang_ir_node *prevLoop; /* * LOOP: - * eval expr (child[0]), updating condcodes - * IF !expr: - * BRK + * BREAK if !expr (child[0]) * body code (child[1]) */ - slang_ir_node *ifThen, *cond, *body, *loop; + slang_ir_node *loop, *cond, *breakIf, *body; loop = new_loop(NULL); @@ -1395,19 +1408,12 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) A->CurLoop = loop; cond = _slang_gen_operation(A, &oper->children[0]); - cond = new_node1(IR_NOT, cond); - cond = _slang_gen_cond(cond); - - ifThen = new_if(cond, - new_break(A->CurLoop), - NULL); - + breakIf = new_break_if_false(A->CurLoop, cond); body = _slang_gen_operation(A, &oper->children[1]); + loop->Children[0] = new_seq(breakIf, body); - loop->Children[0] = new_seq(ifThen, body); - - - A->CurLoop = prevLoop; /* pop loop, restore prev */ + /* pop loop, restore prev */ + A->CurLoop = prevLoop; return loop; } @@ -1423,11 +1429,9 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) /* * LOOP: * body code (child[0]) - * eval expr (child[1]), updating condcodes - * IF !expr: - * BRK + * BREAK if !expr (child[1]) */ - slang_ir_node *ifThen, *cond, *body, *loop; + slang_ir_node *loop, *cond, *breakIf, *body; loop = new_loop(NULL); @@ -1436,18 +1440,12 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) A->CurLoop = loop; body = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_operation(A, &oper->children[1]); - cond = new_node1(IR_NOT, cond); - cond = _slang_gen_cond(cond); + breakIf = new_break_if_false(A->CurLoop, cond); + loop->Children[0] = new_seq(body, breakIf); - ifThen = new_if(cond, - new_break(A->CurLoop), - NULL); - - loop->Children[0] = new_seq(body, ifThen); - - A->CurLoop = prevLoop; /* pop loop, restore prev */ + /* pop loop, restore prev */ + A->CurLoop = prevLoop; return loop; } @@ -1463,13 +1461,11 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) /* * init (child[0]) * LOOP: - * eval expr (child[1]), updating condcodes - * IF !expr: - * BRK + * BREAK if !expr (child[1]) * body code (child[3]) * incr code (child[2]) // XXX continue here */ - slang_ir_node *init, *ifThen, *cond, *body, *loop, *incr; + slang_ir_node *loop, *cond, *breakIf, *body, *init, *incr; init = _slang_gen_operation(A, &oper->children[0]); loop = new_loop(NULL); @@ -1479,21 +1475,14 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) A->CurLoop = loop; cond = _slang_gen_operation(A, &oper->children[1]); - cond = new_node1(IR_NOT, cond); - cond = _slang_gen_cond(cond); - - ifThen = new_if(cond, - new_break(A->CurLoop), - NULL); - + breakIf = new_break_if_false(A->CurLoop, cond); body = _slang_gen_operation(A, &oper->children[3]); - incr = _slang_gen_operation(A, &oper->children[2]); + loop->Children[0] = new_seq(breakIf, + new_seq(body, incr)); - loop->Children[0] = new_seq(ifThen, - new_seq(body,incr)); - - A->CurLoop = prevLoop; /* pop loop, restore prev */ + /* pop loop, restore prev */ + A->CurLoop = prevLoop; return new_seq(init, loop); } @@ -1521,7 +1510,7 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) slang_atom endifAtom = slang_atom_pool_gen(A->atoms, "__endif"); cond = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_cond(cond); + cond = new_cond(cond); /*assert(cond->Store);*/ bra = new_cjump(haveElseClause ? elseAtom : endifAtom, 0); tree = new_seq(cond, bra); @@ -1572,7 +1561,7 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) slang_ir_node *ifNode, *cond, *ifBody, *elseBody; cond = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_cond(cond); + cond = new_cond(cond); ifBody = _slang_gen_operation(A, &oper->children[1]); if (haveElseClause) elseBody = _slang_gen_operation(A, &oper->children[2]); @@ -1662,7 +1651,7 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper) /* eval condition */ cond = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_cond(cond); + cond = new_cond(cond); tree = new_seq(tmpDecl, cond); /* jump if false to "alt" label */ @@ -2245,9 +2234,6 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) case slang_oper_block_no_new_scope: /* list of operations */ - /* - assert(oper->num_children > 0); - */ if (oper->num_children > 0) { slang_ir_node *n, *tree = NULL; @@ -2287,7 +2273,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) break; case slang_oper_expression: return _slang_gen_operation(A, &oper->children[0]); - break; + case slang_oper_for: return _slang_gen_for(A, oper); case slang_oper_do: diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 6e2394f2656..d83880a26f2 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -332,6 +332,9 @@ slang_print_ir(const slang_ir_node *n, int indent) case IR_BREAK: printf("BREAK\n"); break; + case IR_BREAK_IF_FALSE: + printf("BREAK_IF_FALSE\n"); + break; case IR_VAR: printf("VAR %s%s at %s store %p\n", @@ -1153,13 +1156,17 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) */ for (ir = n->BranchNode; ir; ir = ir->BranchNode) { struct prog_instruction *inst = prog->Instructions + ir->InstLocation; - if (ir->Opcode == IR_BREAK) { + if (ir->Opcode == IR_BREAK || + ir->Opcode == IR_BREAK_IF_FALSE || + ir->Opcode == IR_BREAK_IF_TRUE) { assert(inst->Opcode == OPCODE_BRK || inst->Opcode == OPCODE_BRA); inst->BranchTarget = endInstLoc + 1; } else { - assert(ir->Opcode == IR_CONT); + assert(ir->Opcode == IR_CONT || + ir->Opcode == IR_CONT_IF_FALSE || + ir->Opcode == IR_CONT_IF_TRUE); assert(inst->Opcode == OPCODE_CONT || inst->Opcode == OPCODE_BRA); /* XXX goto top of loop instead! */ @@ -1191,6 +1198,35 @@ emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } +/** + * Conditional loop continue/break. + */ +static struct prog_instruction * +emit_cont_break_if(slang_var_table *vt, slang_ir_node *n, + struct gl_program *prog, GLboolean breakTrue) +{ + gl_inst_opcode opcode; + struct prog_instruction *inst; + + /* evaluate condition expr, setting cond codes */ + inst = emit(vt, n->Children[0], prog); + assert(inst); + inst->CondUpdate = GL_TRUE; + + n->InstLocation = prog->NumInstructions; + if (EmitHighLevelInstructions) { + opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; + } + else { + opcode = OPCODE_BRA; + } + inst = new_instruction(prog, opcode); + inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ; + return inst; +} + + + /** * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term). * Ex: fix_swizzle("zyNN") -> "zyyy" @@ -1407,6 +1443,10 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_LOOP: return emit_loop(vt, n, prog); + case IR_BREAK_IF_FALSE: + return emit_cont_break_if(vt, n, prog, GL_FALSE); + case IR_BREAK_IF_TRUE: + return emit_cont_break_if(vt, n, prog, GL_TRUE); case IR_BREAK: /* fall-through */ case IR_CONT: -- cgit v1.2.3 From fbf0f400b743686ccdf78b927fd5de477d764a9d Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 8 Feb 2007 14:10:54 -0700 Subject: fix broken BRA for return stmts --- src/mesa/shader/slang/slang_codegen.c | 6 +++--- src/mesa/shader/slang/slang_emit.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 6671f31c478..f71bbead0a6 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1407,7 +1407,7 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) prevLoop = A->CurLoop; A->CurLoop = loop; - cond = _slang_gen_operation(A, &oper->children[0]); + cond = new_cond(_slang_gen_operation(A, &oper->children[0])); breakIf = new_break_if_false(A->CurLoop, cond); body = _slang_gen_operation(A, &oper->children[1]); loop->Children[0] = new_seq(breakIf, body); @@ -1440,7 +1440,7 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) A->CurLoop = loop; body = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_operation(A, &oper->children[1]); + cond = new_cond(_slang_gen_operation(A, &oper->children[1])); breakIf = new_break_if_false(A->CurLoop, cond); loop->Children[0] = new_seq(body, breakIf); @@ -1474,7 +1474,7 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) prevLoop = A->CurLoop; A->CurLoop = loop; - cond = _slang_gen_operation(A, &oper->children[1]); + cond = new_cond(_slang_gen_operation(A, &oper->children[1])); breakIf = new_break_if_false(A->CurLoop, cond); body = _slang_gen_operation(A, &oper->children[3]); incr = _slang_gen_operation(A, &oper->children[2]); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index d83880a26f2..e5727120267 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -487,6 +487,7 @@ new_instruction(struct gl_program *prog, gl_inst_opcode opcode) prog->NumInstructions++; _mesa_init_instructions(inst, 1); inst->Opcode = opcode; + inst->BranchTarget = -1; /* invalid */ return inst; } -- cgit v1.2.3 From 6230ae7faf46e0ebcb4807df051c8b50482089dd Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 8 Feb 2007 15:09:47 -0700 Subject: cont at top of loop, little clean-ups --- src/mesa/shader/slang/slang_emit.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index e5727120267..c43f79cc727 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -40,7 +40,7 @@ #define PEEPHOLE_OPTIMIZATIONS 1 -#define ANNOTATE 1 +#define ANNOTATE 0 static GLboolean EmitHighLevelInstructions = GL_TRUE; @@ -59,7 +59,7 @@ typedef struct -static slang_ir_info IrInfo[] = { +static const slang_ir_info IrInfo[] = { /* binary ops */ { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 }, { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 }, @@ -124,7 +124,7 @@ static slang_ir_info IrInfo[] = { }; -static slang_ir_info * +static const slang_ir_info * slang_find_ir_info(slang_ir_opcode opcode) { GLuint i; @@ -334,6 +334,11 @@ slang_print_ir(const slang_ir_node *n, int indent) break; case IR_BREAK_IF_FALSE: printf("BREAK_IF_FALSE\n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_BREAK_IF_TRUE: + printf("BREAK_IF_TRUE\n"); + slang_print_ir(n->Children[0], indent+3); break; case IR_VAR: @@ -1157,11 +1162,13 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) */ for (ir = n->BranchNode; ir; ir = ir->BranchNode) { struct prog_instruction *inst = prog->Instructions + ir->InstLocation; + assert(inst->BranchTarget < 0); if (ir->Opcode == IR_BREAK || ir->Opcode == IR_BREAK_IF_FALSE || ir->Opcode == IR_BREAK_IF_TRUE) { assert(inst->Opcode == OPCODE_BRK || inst->Opcode == OPCODE_BRA); + /* go to instruction after end of loop */ inst->BranchTarget = endInstLoc + 1; } else { @@ -1170,8 +1177,8 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) ir->Opcode == IR_CONT_IF_TRUE); assert(inst->Opcode == OPCODE_CONT || inst->Opcode == OPCODE_BRA); - /* XXX goto top of loop instead! */ - inst->BranchTarget = endInstLoc; + /* to go instruction at top of loop */ + inst->BranchTarget = beginInstLoc; } } return NULL; -- cgit v1.2.3 From c0a9f554be0b82f2e6ce2d9318854ecd24a1a890 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 8 Feb 2007 17:11:18 -0700 Subject: optimize conditional breaks/continues --- src/mesa/shader/slang/slang_codegen.c | 90 ++++++++++++++++++++++++++++------- src/mesa/shader/slang/slang_emit.c | 20 +++++--- 2 files changed, 87 insertions(+), 23 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 2da53171ede..7566ad2e9f8 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -614,12 +614,35 @@ new_break(slang_ir_node *loopNode) } +/** + * Make new IR_BREAK_IF_TRUE or IR_BREAK_IF_FALSE node. + */ static slang_ir_node * -new_break_if_false(slang_ir_node *loopNode, slang_ir_node *cond) +new_break_if(slang_ir_node *loopNode, slang_ir_node *cond, GLboolean breakTrue) { - slang_ir_node *n = new_node1(IR_BREAK_IF_FALSE, cond); + slang_ir_node *n; + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + n = new_node1(breakTrue ? IR_BREAK_IF_TRUE : IR_BREAK_IF_FALSE, cond); + if (n) { + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; + } + return n; +} + + +/** + * Make new IR_CONT_IF_TRUE or IR_CONT_IF_FALSE node. + */ +static slang_ir_node * +new_cont_if(slang_ir_node *loopNode, slang_ir_node *cond, GLboolean contTrue) +{ + slang_ir_node *n; assert(loopNode); assert(loopNode->Opcode == IR_LOOP); + n = new_node1(contTrue ? IR_CONT_IF_TRUE : IR_CONT_IF_FALSE, cond); if (n) { /* insert this node at head of linked list */ n->BranchNode = loopNode->BranchNode; @@ -1406,7 +1429,7 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) A->CurLoop = loop; cond = new_cond(_slang_gen_operation(A, &oper->children[0])); - breakIf = new_break_if_false(A->CurLoop, cond); + breakIf = new_break_if(A->CurLoop, cond, GL_FALSE); body = _slang_gen_operation(A, &oper->children[1]); loop->Children[0] = new_seq(breakIf, body); @@ -1439,7 +1462,7 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) body = _slang_gen_operation(A, &oper->children[0]); cond = new_cond(_slang_gen_operation(A, &oper->children[1])); - breakIf = new_break_if_false(A->CurLoop, cond); + breakIf = new_break_if(A->CurLoop, cond, GL_FALSE); loop->Children[0] = new_seq(body, breakIf); /* pop loop, restore prev */ @@ -1473,7 +1496,7 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) A->CurLoop = loop; cond = new_cond(_slang_gen_operation(A, &oper->children[1])); - breakIf = new_break_if_false(A->CurLoop, cond); + breakIf = new_break_if(A->CurLoop, cond, GL_FALSE); body = _slang_gen_operation(A, &oper->children[3]); incr = _slang_gen_operation(A, &oper->children[2]); loop->Children[0] = new_seq(breakIf, @@ -1536,6 +1559,23 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) } +/** + * Determine if the given operation is of a specific type. + */ +static GLboolean +is_operation_type(const const slang_operation *oper, slang_operation_type type) +{ + if (oper->type == type) + return GL_TRUE; + else if ((oper->type == slang_oper_block_new_scope || + oper->type == slang_oper_block_no_new_scope) && + oper->num_children == 1) + return is_operation_type(&oper->children[0], type); + else + return GL_FALSE; +} + + /** * Generate IR tree for an if/then/else conditional using high-level * IR_IF instruction. @@ -1551,24 +1591,40 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) * else-body code * ENDIF */ - /* XXX special cases to check for: - * if body of conditiona is just a "break", emit a conditional break - * instruction. - */ const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); slang_ir_node *ifNode, *cond, *ifBody, *elseBody; cond = _slang_gen_operation(A, &oper->children[0]); cond = new_cond(cond); - ifBody = _slang_gen_operation(A, &oper->children[1]); - if (haveElseClause) - elseBody = _slang_gen_operation(A, &oper->children[2]); - else - elseBody = NULL; - - ifNode = new_if(cond, ifBody, elseBody); - return ifNode; + if (is_operation_type(&oper->children[1], slang_oper_break)) { + /* Special case: generate a conditional break */ + ifBody = new_break_if(A->CurLoop, cond, GL_TRUE); + if (haveElseClause) { + elseBody = _slang_gen_operation(A, &oper->children[2]); + return new_seq(ifBody, elseBody); + } + return ifBody; + } + else if (is_operation_type(&oper->children[1], slang_oper_continue)) { + /* Special case: generate a conditional break */ + ifBody = new_cont_if(A->CurLoop, cond, GL_TRUE); + if (haveElseClause) { + elseBody = _slang_gen_operation(A, &oper->children[2]); + return new_seq(ifBody, elseBody); + } + return ifBody; + } + else { + /* general case */ + ifBody = _slang_gen_operation(A, &oper->children[1]); + if (haveElseClause) + elseBody = _slang_gen_operation(A, &oper->children[2]); + else + elseBody = NULL; + ifNode = new_if(cond, ifBody, elseBody); + return ifNode; + } } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index c43f79cc727..1b43042e2d9 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1156,9 +1156,9 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) beginInst->BranchTarget = prog->NumInstructions - 1; } - /* Done emitting loop code. Now walk over the loop's linked list - * of BREAK and CONT nodes, filling in their BranchTarget fields - * (which will point to the ENDLOOP or ENDLOOP+1 instructions). + /* Done emitting loop code. Now walk over the loop's linked list of + * BREAK and CONT nodes, filling in their BranchTarget fields (which + * will point to the ENDLOOP+1 or BGNLOOP instructions, respectively). */ for (ir = n->BranchNode; ir; ir = ir->BranchNode) { struct prog_instruction *inst = prog->Instructions + ir->InstLocation; @@ -1186,7 +1186,8 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /** - * Emit code for IR_CONT or IR_BREAK. + * "Continue" or "break" statement. + * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted. */ static struct prog_instruction * emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) @@ -1207,7 +1208,8 @@ emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /** - * Conditional loop continue/break. + * Conditional "continue" or "break" statement. + * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted. */ static struct prog_instruction * emit_cont_break_if(slang_var_table *vt, slang_ir_node *n, @@ -1223,7 +1225,11 @@ emit_cont_break_if(slang_var_table *vt, slang_ir_node *n, n->InstLocation = prog->NumInstructions; if (EmitHighLevelInstructions) { - opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; + if (n->Opcode == IR_CONT_IF_TRUE || + n->Opcode == IR_CONT_IF_FALSE) + opcode = OPCODE_CONT; + else + opcode = OPCODE_BRK; } else { opcode = OPCODE_BRA; @@ -1452,8 +1458,10 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_LOOP: return emit_loop(vt, n, prog); case IR_BREAK_IF_FALSE: + case IR_CONT_IF_FALSE: return emit_cont_break_if(vt, n, prog, GL_FALSE); case IR_BREAK_IF_TRUE: + case IR_CONT_IF_TRUE: return emit_cont_break_if(vt, n, prog, GL_TRUE); case IR_BREAK: /* fall-through */ -- cgit v1.2.3 From b3893baf80f913499092d4339b3131527b912188 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 9 Feb 2007 14:19:12 -0700 Subject: comments, etc --- src/mesa/shader/slang/slang_emit.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 1b43042e2d9..b15d7372a7d 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -43,9 +43,11 @@ #define ANNOTATE 0 +/* XXX temporarily here */ static GLboolean EmitHighLevelInstructions = GL_TRUE; + /** * Assembly and IR info */ @@ -116,7 +118,7 @@ static const slang_ir_info IrInfo[] = { { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 }, { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 }, { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 }, - { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, + { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */ { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 }, { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 }, { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 }, @@ -340,6 +342,14 @@ slang_print_ir(const slang_ir_node *n, int indent) printf("BREAK_IF_TRUE\n"); slang_print_ir(n->Children[0], indent+3); break; + case IR_CONT_IF_FALSE: + printf("CONT_IF_FALSE\n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_CONT_IF_TRUE: + printf("CONT_IF_TRUE\n"); + slang_print_ir(n->Children[0], indent+3); + break; case IR_VAR: printf("VAR %s%s at %s store %p\n", @@ -358,11 +368,16 @@ slang_print_ir(const slang_ir_node *n, int indent) slang_print_ir(n->Children[0], indent+3); break; case IR_FLOAT: - printf("FLOAT %f %f %f %f\n", + printf("FLOAT %g %g %g %g\n", n->Value[0], n->Value[1], n->Value[2], n->Value[3]); break; case IR_I_TO_F: - printf("INT_TO_FLOAT %d\n", (int) n->Value[0]); + printf("INT_TO_FLOAT\n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_F_TO_I: + printf("FLOAT_TO_INT\n"); + slang_print_ir(n->Children[0], indent+3); break; case IR_SWIZZLE: printf("SWIZZLE %s of (store %p) \n", @@ -1386,6 +1401,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_FLOOR: case IR_FRAC: case IR_F_TO_I: + case IR_I_TO_F: case IR_ABS: case IR_SIN: case IR_COS: -- cgit v1.2.3 From d003877c669414474fbe00ca423ebbb462939529 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 16 Feb 2007 08:58:42 -0700 Subject: implement IR_I_TO_F --- src/mesa/shader/slang/slang_emit.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/mesa/shader/slang/slang_emit.c') diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index b15d7372a7d..955f428b95b 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1394,6 +1394,12 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_SWIZZLE: return emit_swizzle(vt, n, prog); + case IR_I_TO_F: + { + n->Store = n->Children[0]->Store; + } + return NULL; + /* Simple arithmetic */ /* unary */ case IR_RSQ: @@ -1401,7 +1407,6 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_FLOOR: case IR_FRAC: case IR_F_TO_I: - case IR_I_TO_F: case IR_ABS: case IR_SIN: case IR_COS: -- cgit v1.2.3