From 9e9ae280e215988287b0f875c81bc2e146b9f5dd Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 4 May 2012 13:09:38 -0700 Subject: [PATCH] Revert "i965/fs: Jump from discard statements to the end of the program when done." This reverts commit 31866308fcf989df992ace28b5b986c3d3770e90. Fixes piglit glsl-fs-discard-exit-3 and unigine tropics rendering. Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_eu.h | 1 - src/mesa/drivers/dri/i965/brw_eu_emit.c | 53 +++------------------- src/mesa/drivers/dri/i965/brw_fs.h | 22 --------- src/mesa/drivers/dri/i965/brw_fs_emit.cpp | 55 ----------------------- 4 files changed, 5 insertions(+), 126 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index 675b50a1456..e052ee081ac 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -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); diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 597157e2e51..179b59ac6fb 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -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 and should be the same. In case - * of the halt instruction inside conditional code block, the - * should be the end of the program, and the 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; diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 82ec4a5ce74..f04c6fc7351 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -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. diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp index 0bdeb71ca4a..a4b71de49a0 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp @@ -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); -- 2.30.2