mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 22:08:26 +02:00
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).
This commit is contained in:
parent
14150bc856
commit
7dc449d406
1 changed files with 12 additions and 3 deletions
|
|
@ -677,6 +677,7 @@ static struct prog_instruction *
|
||||||
emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
|
emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||||
{
|
{
|
||||||
struct prog_instruction *inst;
|
struct prog_instruction *inst;
|
||||||
|
slang_ir_node tmpNode;
|
||||||
|
|
||||||
assert(n->Opcode == IR_CLAMP);
|
assert(n->Opcode == IR_CLAMP);
|
||||||
/* ch[0] = value
|
/* 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[1]);
|
||||||
emit(emitInfo, n->Children[2]);
|
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]) */
|
/* tmp = max(ch[0], ch[1]) */
|
||||||
inst = new_instruction(emitInfo, OPCODE_MAX);
|
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[0], n->Children[0]->Store);
|
||||||
storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->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);
|
inst = new_instruction(emitInfo, OPCODE_MIN);
|
||||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
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);
|
storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store);
|
||||||
|
|
||||||
|
free_temp_storage(emitInfo->vt, &tmpNode);
|
||||||
|
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue