Revert "i965/fs: Jump from discard statements to the end of the program when done."
authorEric Anholt <eric@anholt.net>
Fri, 4 May 2012 20:09:38 +0000 (13:09 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 15 May 2012 00:03:53 +0000 (17:03 -0700)
This reverts commit 31866308fcf989df992ace28b5b986c3d3770e90.

Fixes piglit glsl-fs-discard-exit-3 and unigine tropics rendering.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_fs_emit.cpp

index 675b50a145680a3b3affc4ceffcaadac0cf6d060..e052ee081acba8b12f5fe94a78332ec5e54e205e 100644 (file)
@@ -1047,7 +1047,6 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p);
 struct brw_instruction *brw_BREAK(struct brw_compile *p);
 struct brw_instruction *brw_CONT(struct brw_compile *p);
 struct brw_instruction *gen6_CONT(struct brw_compile *p);
-struct brw_instruction *gen6_HALT(struct brw_compile *p);
 /* Forward jumps:
  */
 void brw_land_fwd_jump(struct brw_compile *p, int jmp_insn_idx);
index 597157e2e514fbb566a1a5e97fb8ec2b25690e64..179b59ac6fb3c32984cd24ba8cb0e8598dc1e3a8 100644 (file)
@@ -1421,20 +1421,6 @@ struct brw_instruction *brw_CONT(struct brw_compile *p)
    return insn;
 }
 
-struct brw_instruction *gen6_HALT(struct brw_compile *p)
-{
-   struct brw_instruction *insn;
-
-   insn = next_insn(p, BRW_OPCODE_HALT);
-   brw_set_dest(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
-   brw_set_src0(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
-   brw_set_src1(p, insn, brw_imm_d(0x0)); /* UIP and JIP, updated later. */
-
-   insn->header.compression_control = BRW_COMPRESSION_NONE;
-   insn->header.execution_size = BRW_EXECUTE_8;
-   return insn;
-}
-
 /* DO/WHILE loop:
  *
  * The DO/WHILE is just an unterminated loop -- break or continue are
@@ -2491,8 +2477,8 @@ brw_find_next_block_end(struct brw_compile *p, int start)
         return ip;
       }
    }
-
-   return 0;
+   assert(!"not reached");
+   return start + 1;
 }
 
 /* There is no DO instruction on gen6, so to find the end of the loop
@@ -2521,7 +2507,7 @@ brw_find_loop_end(struct brw_compile *p, int start)
 }
 
 /* After program generation, go back and update the UIP and JIP of
- * BREAK, CONT, and HALT instructions to their correct locations.
+ * BREAK and CONT instructions to their correct locations.
  */
 void
 brw_set_uip_jip(struct brw_compile *p)
@@ -2535,47 +2521,18 @@ brw_set_uip_jip(struct brw_compile *p)
 
    for (ip = 0; ip < p->nr_insn; ip++) {
       struct brw_instruction *insn = &p->store[ip];
-      int block_end_ip = 0;
-
-      if (insn->header.opcode == BRW_OPCODE_BREAK ||
-         insn->header.opcode == BRW_OPCODE_CONTINUE ||
-         insn->header.opcode == BRW_OPCODE_HALT) {
-        block_end_ip = brw_find_next_block_end(p, ip);
-      }
 
       switch (insn->header.opcode) {
       case BRW_OPCODE_BREAK:
-        assert(block_end_ip != 0);
-        insn->bits3.break_cont.jip = br * (block_end_ip - ip);
+        insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
         /* Gen7 UIP points to WHILE; Gen6 points just after it */
         insn->bits3.break_cont.uip =
            br * (brw_find_loop_end(p, ip) - ip + (intel->gen == 6 ? 1 : 0));
         break;
       case BRW_OPCODE_CONTINUE:
-        assert(block_end_ip != 0);
-        insn->bits3.break_cont.jip = br * (block_end_ip - ip);
+        insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
         insn->bits3.break_cont.uip = br * (brw_find_loop_end(p, ip) - ip);
 
-        assert(insn->bits3.break_cont.uip != 0);
-        assert(insn->bits3.break_cont.jip != 0);
-        break;
-      case BRW_OPCODE_HALT:
-        /* From the Sandy Bridge PRM (volume 4, part 2, section 8.3.19):
-         *
-         *    "In case of the halt instruction not inside any conditional code
-         *     block, the value of <JIP> and <UIP> should be the same. In case
-         *     of the halt instruction inside conditional code block, the <UIP>
-         *     should be the end of the program, and the <JIP> should be end of
-         *     the most inner conditional code block."
-         *
-         * The uip will have already been set by whoever set up the
-         * instruction.
-         */
-        if (block_end_ip == 0) {
-           insn->bits3.break_cont.jip = insn->bits3.break_cont.uip;
-        } else {
-           insn->bits3.break_cont.jip = br * (block_end_ip - ip);
-        }
         assert(insn->bits3.break_cont.uip != 0);
         assert(insn->bits3.break_cont.jip != 0);
         break;
index 82ec4a5ce74c807787a33184d803271779e42cb3..f04c6fc73510b5352c0e1fb67478a91b8a1d1630 100644 (file)
@@ -175,26 +175,6 @@ static const fs_reg reg_undef;
 static const fs_reg reg_null_f(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_F);
 static const fs_reg reg_null_d(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_D);
 
-class ip_record : public exec_node {
-public:
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
-   ip_record(int ip)
-   {
-      this->ip = ip;
-   }
-
-   int ip;
-};
-
 class fs_inst : public exec_node {
 public:
    /* Callers of this ralloc-based new need not call delete. It's
@@ -521,7 +501,6 @@ public:
    bool remove_duplicate_mrf_writes();
    bool virtual_grf_interferes(int a, int b);
    void schedule_instructions();
-   void patch_discard_jumps_to_fb_writes();
    void fail(const char *msg, ...);
 
    void push_force_uncompressed();
@@ -606,7 +585,6 @@ public:
    struct gl_shader_program *prog;
    void *mem_ctx;
    exec_list instructions;
-   exec_list discard_halt_patches;
 
    /* Delayed setup of c->prog_data.params[] due to realloc of
     * ParamValues[] during compile.
index 0bdeb71ca4a2bb27099f07bac14898ebcf3bc522..a4b71de49a08a5d562097f44f058af32117fadfb 100644 (file)
@@ -37,56 +37,12 @@ extern "C" {
 #include "brw_fs_cfg.h"
 #include "glsl/ir_print_visitor.h"
 
-void
-fs_visitor::patch_discard_jumps_to_fb_writes()
-{
-   if (intel->gen < 6 || this->discard_halt_patches.is_empty())
-      return;
-
-   /* There is a somewhat strange undocumented requirement of using
-    * HALT, according to the simulator.  If some channel has HALTed to
-    * a particular UIP, then by the end of the program, every channel
-    * must have HALTed to that UIP.  Furthermore, the tracking is a
-    * stack, so you can't do the final halt of a UIP after starting
-    * halting to a new UIP.
-    *
-    * Symptoms of not emitting this instruction on actual hardware
-    * included GPU hangs and sparkly rendering on the piglit discard
-    * tests.
-    */
-   struct brw_instruction *last_halt = gen6_HALT(p);
-   last_halt->bits3.break_cont.uip = 2;
-   last_halt->bits3.break_cont.jip = 2;
-
-   int ip = p->nr_insn;
-
-   foreach_list(node, &this->discard_halt_patches) {
-      ip_record *patch_ip = (ip_record *)node;
-      struct brw_instruction *patch = &p->store[patch_ip->ip];
-      int br = (intel->gen >= 5) ? 2 : 1;
-
-      /* HALT takes a distance from the pre-incremented IP, so '1'
-       * would be the next instruction after jmpi.
-       */
-      assert(patch->header.opcode == BRW_OPCODE_HALT);
-      patch->bits3.break_cont.uip = (ip - patch_ip->ip) * br;
-   }
-
-   this->discard_halt_patches.make_empty();
-}
-
 void
 fs_visitor::generate_fb_write(fs_inst *inst)
 {
    bool eot = inst->eot;
    struct brw_reg implied_header;
 
-   /* Note that the jumps emitted to this point mean that the g0 ->
-    * base_mrf setup must be inside of this function, so that we jump
-    * to a point containing it.
-    */
-   patch_discard_jumps_to_fb_writes();
-
    /* Header is 2 regs, g0 and g1 are the contents. g0 will be implied
     * move, here's g1.
     */
@@ -527,17 +483,6 @@ fs_visitor::generate_discard(fs_inst *inst)
       brw_set_mask_control(p, BRW_MASK_DISABLE);
       brw_AND(p, g1, f0, g1);
       brw_pop_insn_state(p);
-
-      /* GLSL 1.30+ say that discarded channels should stop executing
-       * (so, for example, an infinite loop that would otherwise in
-       * just that channel does not occur.
-       *
-       * This HALT will be patched up at FB write time to point UIP at
-       * the end of the program, and at brw_uip_jip() JIP will be set
-       * to the end of the current block (or the program).
-       */
-      this->discard_halt_patches.push_tail(new(mem_ctx) ip_record(p->nr_insn));
-      gen6_HALT(p);
    } else {
       struct brw_reg g0 = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);