[Mesa-dev] [PATCH] svga: fix register collision issue in emit_conditional()

Brian Paul brianp at vmware.com
Tue Jul 3 14:54:10 PDT 2012


If the 'dst' register is the same as the 'pass' register we'll generate
invalid code.  Use a temporary register in that case.
---
 src/gallium/drivers/svga/svga_tgsi_insn.c |   32 +++++++++++++++++++++++++++-
 1 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c
index c3a74c4..4cf5cf4 100644
--- a/src/gallium/drivers/svga/svga_tgsi_insn.c
+++ b/src/gallium/drivers/svga/svga_tgsi_insn.c
@@ -1245,6 +1245,20 @@ static boolean emit_kilp(struct svga_shader_emitter *emit,
    return submit_op0( emit, inst, temp );
 }
 
+
+/**
+ * Test if r1 and r2 are the same register.
+ */
+static boolean
+same_register(struct src_register r1, struct src_register r2)
+{
+   return (r1.base.num == r2.base.num &&
+           r1.base.type_upper == r2.base.type_upper &&
+           r1.base.type_lower == r2.base.type_lower);
+}
+
+
+
 /* Implement conditionals by initializing destination reg to 'fail',
  * then set predicate reg with UFOP_SETP, then move 'pass' to dest
  * based on predicate reg.
@@ -1264,6 +1278,7 @@ emit_conditional(struct svga_shader_emitter *emit,
 {
    SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
    SVGA3dShaderInstToken setp_token, mov_token;
+   struct src_register pass2;
    setp_token = inst_token( SVGA3DOP_SETP );
 
    switch (compare_func) {
@@ -1295,6 +1310,19 @@ emit_conditional(struct svga_shader_emitter *emit,
       break;
    }
 
+   if (same_register(src(dst), pass)) {
+      /* We'll get bad results if the dst and pass registers are the same
+       * so use a temp register containing pass.
+       */
+      SVGA3dShaderDestToken temp = get_temp(emit);
+      if (!submit_op1(emit, inst_token(SVGA3DOP_MOV), temp, pass))
+         return FALSE;
+      pass2 = src(temp);
+   }
+   else {
+      pass2 = pass;
+   }
+
    /* SETP src0, COMPOP, src1 */
    if (!submit_op2( emit, setp_token, pred_reg,
                     src0, src1 ))
@@ -1307,14 +1335,14 @@ emit_conditional(struct svga_shader_emitter *emit,
                     fail ))
       return FALSE;
 
-   /* MOV dst, pass (predicated)
+   /* MOV dst, pass2 (predicated)
     *
     * Note that the predicate reg (and possible modifiers) is passed
     * as the first source argument.
     */
    mov_token.predicated = 1;
    if (!submit_op2( emit, mov_token, dst,
-                    src( pred_reg ), pass ))
+                    src( pred_reg ), pass2 ))
       return FALSE;
 
    return TRUE;
-- 
1.7.7.3



More information about the mesa-dev mailing list