i965: Add support for gen6 CONTINUE instruction emit.
authorEric Anholt <eric@anholt.net>
Wed, 1 Dec 2010 22:02:14 +0000 (14:02 -0800)
committerEric Anholt <eric@anholt.net>
Thu, 2 Dec 2010 00:14:34 +0000 (16:14 -0800)
At this point, piglit tests for fragment shader loops are working.

src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_fs.cpp

index df5ce56ba616ac96abbe6cbf175beb07fa7d2156..a4904b7098a0fd474ed87dcff569ac8b8ea91aa7 100644 (file)
@@ -954,6 +954,8 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
               struct brw_instruction *patch_insn);
 
 struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count);
+struct brw_instruction *brw_CONT_gen6(struct brw_compile *p,
+                                     struct brw_instruction *do_insn);
 struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count);
 /* Forward jumps:
  */
index 7eb7bdfa1eeefc46bdbd06deea45865db5a6a0c0..945f50d11069cbc48e31ca84ebe13f6516886008 100644 (file)
@@ -1050,6 +1050,26 @@ struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count)
    return insn;
 }
 
+struct brw_instruction *brw_CONT_gen6(struct brw_compile *p,
+                                     struct brw_instruction *do_insn)
+{
+   struct brw_instruction *insn;
+   int br = 2;
+
+   insn = next_insn(p, BRW_OPCODE_CONTINUE);
+   brw_set_dest(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+   brw_set_src0(insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+   brw_set_dest(insn, brw_ip_reg());
+   brw_set_src0(insn, brw_ip_reg());
+   brw_set_src1(insn, brw_imm_d(0x0));
+
+   insn->bits3.break_cont.uip = br * (do_insn - insn);
+
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.execution_size = BRW_EXECUTE_8;
+   return insn;
+}
+
 struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count)
 {
    struct brw_instruction *insn;
@@ -2087,7 +2107,9 @@ brw_set_uip_jip(struct brw_compile *p)
         /* JIP is set at CONTINUE emit time, since that's when we
          * know where the start of the loop is.
          */
-        insn->bits3.break_cont.uip = br * (brw_find_next_block_end(p, ip) - ip);
+        insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
+        assert(insn->bits3.break_cont.uip != 0);
+        assert(insn->bits3.break_cont.jip != 0);
         break;
       }
    }
index 46061c77ed576547359744c2c5a5a68bd59ade5e..ee9ae160bdb3c1bc34eed7c9c18249d68f249127 100644 (file)
@@ -3390,9 +3390,9 @@ fs_visitor::generate_code()
       case BRW_OPCODE_CONTINUE:
         /* FINISHME: We need to write the loop instruction support still. */
         if (intel->gen >= 6)
-           this->fail = true;
-
-        brw_CONT(p, if_depth_in_loop[loop_stack_depth]);
+           brw_CONT_gen6(p, loop_stack[loop_stack_depth - 1]);
+        else
+           brw_CONT(p, if_depth_in_loop[loop_stack_depth]);
         brw_set_predicate_control(p, BRW_PREDICATE_NONE);
         break;