summaryrefslogtreecommitdiff
path: root/src/mesa/shader
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2008-03-14 13:59:32 -0600
committerBrian <brian.paul@tungstengraphics.com>2008-03-14 13:59:32 -0600
commit868193d54efd6b181fdd3bacf6c88d5ef5a6bc4c (patch)
treef8b2ee64d0f8e6636980f0e9edba4ad76e89fa3b /src/mesa/shader
parent42c279a03b4d3529efc0d552c37ace2c82306822 (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/mesa/shader')
-rw-r--r--src/mesa/shader/slang/slang_emit.c15
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;
}