Module: Mesa
Branch: main
Commit: 89873e5e5ce98c811968f38eb7d1a7953476fe97
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=89873e5e5ce98c811968f38eb7d1a7953476fe97

Author: Pavel Ondračka <[email protected]>
Date:   Fri Jun 23 21:14:43 2023 +0200

r300: properly count maximum used register index

The problem is when we have DP2 or DP3 instruction that writes a w
channel like here:

DP3 temp[148].w, -temp[147].xyz_, temp[57].xyz_;

will get pair-converted to

src0.xyz = temp[147], src1.xyz = temp[57]
DP3, -src0.xyz, src1.xyz
DP3 temp[148].w, -src0._, src0._

where the alpha instruction is a basically just a replicate of the
result from the RGB sub intruction. However the destination register
index in the RBG slot is also 148. Now we pair-schedule and regalloc

src0.xyz = temp[13], src1.xyz = temp[3]
DP3, -src0.xyz, src1.xyz
DP3 temp[3].w, -src0._, src0._

We properly regalloc the alpha channel, but we obviously skip the rgb,
because the writemask is empty there. However when we emit the shader
later, we actually check the number of used regs based on the maximum
used register index and we don't consider the writemasks, so we would
think we use 149 temps. AFAIK the shader would be still completelly OK.
But we would think it hits the HW limits and used a dummy one instead.

Fix this by checking for empty writemasks when marking the registers as
used.

GAINED: shaders/glmark/1-22.shader_test FS

This is also needed to prevent another lost Trine shader from
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23089

Reviewed-by: Filip Gawin <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23838>

---

 src/gallium/drivers/r300/compiler/r500_fragprog_emit.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/r300/compiler/r500_fragprog_emit.c 
b/src/gallium/drivers/r300/compiler/r500_fragprog_emit.c
index 258b873d850..28c05ada69e 100644
--- a/src/gallium/drivers/r300/compiler/r500_fragprog_emit.c
+++ b/src/gallium/drivers/r300/compiler/r500_fragprog_emit.c
@@ -281,8 +281,10 @@ static void emit_paired(struct 
r300_fragment_program_compiler *c, struct rc_pair
 
        code->inst[ip].inst4 |= R500_ALPHA_ADDRD(inst->Alpha.DestIndex);
        code->inst[ip].inst5 |= R500_ALU_RGBA_ADDRD(inst->RGB.DestIndex);
-       use_temporary(code, inst->Alpha.DestIndex);
-       use_temporary(code, inst->RGB.DestIndex);
+       if (inst->Alpha.WriteMask)
+               use_temporary(code, inst->Alpha.DestIndex);
+       if (inst->RGB.WriteMask)
+               use_temporary(code, inst->RGB.DestIndex);
 
        if (inst->RGB.Saturate)
                code->inst[ip].inst0 |= R500_INST_RGB_CLAMP;

Reply via email to