diff options
author | Brian <brian.paul@tungstengraphics.com> | 2008-03-14 13:59:32 -0600 |
---|---|---|
committer | Brian <brian.paul@tungstengraphics.com> | 2008-03-14 13:59:32 -0600 |
commit | 868193d54efd6b181fdd3bacf6c88d5ef5a6bc4c (patch) | |
tree | f8b2ee64d0f8e6636980f0e9edba4ad76e89fa3b /src | |
parent | 42c279a03b4d3529efc0d552c37ace2c82306822 (diff) |
mesa: fix emit_clamp() so that we don't use an output register as temporary
IR_CLAMP is decomposed into OPCODE_MIN+OPCODE_MAX. Allocate a temporary
register for the intermediate value so we don't inadvertantly use an output
register (which are write-only on some GPUs).
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 9947544a08..84c370dc0b 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -677,6 +677,7 @@ static struct prog_instruction * emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) { struct prog_instruction *inst; + slang_ir_node tmpNode; assert(n->Opcode == IR_CLAMP); /* ch[0] = value @@ -722,18 +723,26 @@ emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) emit(emitInfo, n->Children[1]); emit(emitInfo, n->Children[2]); + /* Some GPUs don't allow reading from output registers. So if the + * dest for this clamp() is an output reg, we can't use that reg for + * the intermediate result. Use a temp register instead. + */ + alloc_temp_storage(emitInfo, &tmpNode, n->Store->Size); + /* tmp = max(ch[0], ch[1]) */ inst = new_instruction(emitInfo, OPCODE_MAX); - storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_dst_reg(&inst->DstReg, tmpNode.Store, n->Writemask); storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); - /* tmp = min(tmp, ch[2]) */ + /* n->dest = min(tmp, ch[2]) */ inst = new_instruction(emitInfo, OPCODE_MIN); storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); - storage_to_src_reg(&inst->SrcReg[0], n->Store); + storage_to_src_reg(&inst->SrcReg[0], tmpNode.Store); storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store); + free_temp_storage(emitInfo->vt, &tmpNode); + return inst; } |