struct brw_indirect newvtx0 = brw_indirect(2, 0);
struct brw_indirect newvtx1 = brw_indirect(3, 0);
struct brw_indirect plane_ptr = brw_indirect(4, 0);
- struct brw_instruction *plane_loop;
struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
GLuint hpos_offset = brw_vert_result_to_offset(&c->vue_map,
VERT_RESULT_HPOS);
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- plane_loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
/* if (planemask & 1)
*/
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
}
- brw_WHILE(p, plane_loop);
+ brw_WHILE(p);
brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
struct brw_indirect inlist_ptr = brw_indirect(4, 0);
struct brw_indirect outlist_ptr = brw_indirect(5, 0);
struct brw_indirect freelist_ptr = brw_indirect(6, 0);
- struct brw_instruction *plane_loop;
- struct brw_instruction *vertex_loop;
GLuint hpos_offset = brw_vert_result_to_offset(&c->vue_map,
VERT_RESULT_HPOS);
brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
- plane_loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
/* if (planemask & 1)
*/
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
- vertex_loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
/* vtx = *input_ptr;
*/
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
}
- brw_WHILE(p, vertex_loop);
+ brw_WHILE(p);
/* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
* inlist = outlist
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
}
- brw_WHILE(p, plane_loop);
+ brw_WHILE(p);
}
void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
{
struct brw_compile *p = &c->func;
- struct brw_instruction *loop;
/* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
*/
brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
- loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
brw_clip_emit_vue(c, v0, 1, 0,
(_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT));
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
}
- brw_WHILE(p, loop);
+ brw_WHILE(p);
brw_clip_emit_vue(c, v0, 0, 1,
((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
bool do_offset)
{
struct brw_compile *p = &c->func;
- struct brw_instruction *loop;
struct brw_indirect v0 = brw_indirect(0, 0);
struct brw_indirect v1 = brw_indirect(1, 0);
struct brw_indirect v0ptr = brw_indirect(2, 0);
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
- loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
}
- brw_WHILE(p, loop);
+ brw_WHILE(p);
}
/* v1ptr = &inlist[nr_verts]
brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v1ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
brw_MOV(p, deref_1uw(v1ptr, 0), deref_1uw(v0ptr, 0));
- loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
brw_MOV(p, get_addr_reg(v1), deref_1uw(v0ptr, 2));
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
}
- brw_WHILE(p, loop);
+ brw_WHILE(p);
}
bool do_offset )
{
struct brw_compile *p = &c->func;
- struct brw_instruction *loop;
struct brw_indirect v0 = brw_indirect(0, 0);
struct brw_indirect v0ptr = brw_indirect(2, 0);
brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
- loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
}
- brw_WHILE(p, loop);
+ brw_WHILE(p);
}
p->if_stack_array_size = 16;
p->if_stack =
rzalloc_array(mem_ctx, struct brw_instruction *, p->if_stack_array_size);
+
+ p->loop_stack_depth = 0;
+ p->loop_stack_array_size = 16;
+ p->loop_stack = rzalloc_array(mem_ctx, int, p->loop_stack_array_size);
}
int if_stack_depth;
int if_stack_array_size;
+ /**
+ * loop_stack contains the instruction pointers of the starts of loops which
+ * must be patched (and popped) once the matching WHILE instruction is
+ * encountered.
+ */
+ int *loop_stack;
+ int loop_stack_depth;
+ int loop_stack_array_size;
+
struct brw_glsl_label *first_label; /**< linked list of labels */
struct brw_glsl_call *first_call; /**< linked list of CALs */
};
struct brw_instruction *brw_DO(struct brw_compile *p,
GLuint execute_size);
-struct brw_instruction *brw_WHILE(struct brw_compile *p,
- struct brw_instruction *patch_insn);
+struct brw_instruction *brw_WHILE(struct brw_compile *p);
struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count);
struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count);
}
}
+static void
+push_loop_stack(struct brw_compile *p, struct brw_instruction *inst)
+{
+ if (p->loop_stack_array_size < p->loop_stack_depth) {
+ p->loop_stack_array_size *= 2;
+ p->loop_stack = reralloc(p->mem_ctx, p->loop_stack, int,
+ p->loop_stack_array_size);
+ }
+
+ p->loop_stack[p->loop_stack_depth] = inst - p->store;
+ p->loop_stack_depth++;
+}
+
+static struct brw_instruction *
+get_inner_do_insn(struct brw_compile *p)
+{
+ return &p->store[p->loop_stack[p->loop_stack_depth - 1]];
+}
+
/* EU takes the value from the flag register and pushes it onto some
* sort of a stack (presumably merging with any flag value already on
* the stack). Within an if block, the flags at the top of the stack
struct intel_context *intel = &p->brw->intel;
if (intel->gen >= 6 || p->single_program_flow) {
+ push_loop_stack(p, &p->store[p->nr_insn]);
return &p->store[p->nr_insn];
} else {
struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO);
+ push_loop_stack(p, insn);
+
/* Override the defaults for this instruction:
*/
brw_set_dest(p, insn, brw_null_reg());
-struct brw_instruction *brw_WHILE(struct brw_compile *p,
- struct brw_instruction *do_insn)
+struct brw_instruction *brw_WHILE(struct brw_compile *p)
{
struct intel_context *intel = &p->brw->intel;
- struct brw_instruction *insn;
+ struct brw_instruction *insn, *do_insn;
GLuint br = 1;
+ do_insn = get_inner_do_insn(p);
+ p->loop_stack_depth--;
+
if (intel->gen >= 5)
br = 2;
assert(loop_stack_depth > 0);
loop_stack_depth--;
- inst0 = inst1 = brw_WHILE(p, loop_stack[loop_stack_depth]);
+ inst0 = inst1 = brw_WHILE(p);
if (intel->gen < 6) {
/* patch all the BREAK/CONT instructions from last BGNLOOP */
while (inst0 > loop_stack[loop_stack_depth]) {
assert(loop_stack_depth > 0);
loop_stack_depth--;
- inst0 = inst1 = brw_WHILE(p, loop_stack[loop_stack_depth]);
+ inst0 = inst1 = brw_WHILE(p);
if (intel->gen < 6) {
/* patch all the BREAK/CONT instructions from last BGNLOOP */
while (inst0 > loop_stack[loop_stack_depth]) {
if (intel->gen == 5)
br = 2;
- inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
+ inst0 = inst1 = brw_WHILE(p);
if (intel->gen < 6) {
/* patch all the BREAK/CONT instructions from last BEGINLOOP */