diff options
author | Zhenyu Wang <[email protected]> | 2010-10-14 10:54:53 +0800 |
---|---|---|
committer | Zhenyu Wang <[email protected]> | 2010-10-14 11:24:42 +0800 |
commit | e8e79c1d7eed0f5ae8820611cb86bdbd6ce595e6 (patch) | |
tree | a3483b9f1ee6f525ee55fad1a1374fa0099afd4b | |
parent | a57ef244fc55476660f9fb76982130c5c0b25163 (diff) |
i965: Fix GS hang on Sandybridge
Don't use r0 for FF_SYNC dest reg on Sandybridge, which would
smash FFID field in GS payload, that cause later URB write fail.
Also not use r0 in any URB write requiring allocate.
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_eu_emit.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_gs.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_gs.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_gs_emit.c | 54 |
4 files changed, 46 insertions, 14 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index f9aa5f7efef..41286382d0e 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -1848,7 +1848,8 @@ void brw_ff_sync(struct brw_compile *p, if (intel->gen >= 6) { brw_push_insn_state(p); brw_set_mask_control( p, BRW_MASK_DISABLE ); - brw_MOV(p, brw_message_reg(msg_reg_nr), src0); + brw_MOV(p, retype(brw_message_reg(msg_reg_nr), BRW_REGISTER_TYPE_UD), + retype(src0, BRW_REGISTER_TYPE_UD)); brw_pop_insn_state(p); src0 = brw_message_reg(msg_reg_nr); } diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index ad178d84b65..cfcc8ea4d6a 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -96,8 +96,6 @@ static void compile_gs_prog( struct brw_context *brw, brw_gs_quad_strip( &c, key ); break; case GL_LINE_LOOP: - /* XXX fix GS hang issue */ - assert(intel->gen < 6); brw_gs_lines( &c ); break; case GL_LINES: diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h index 813b8d447ae..7e3531086f9 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.h +++ b/src/mesa/drivers/dri/i965/brw_gs.h @@ -56,6 +56,7 @@ struct brw_gs_compile { struct { struct brw_reg R0; struct brw_reg vertex[MAX_GS_VERTS]; + struct brw_reg temp; } reg; /* 3 different ways of expressing vertex size: diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c index a01d5576f8c..e1f751fdaa4 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c @@ -58,6 +58,8 @@ static void brw_gs_alloc_regs( struct brw_gs_compile *c, i += c->nr_regs; } + c->reg.temp = brw_vec8_grf(i, 0); + c->prog_data.urb_read_length = c->nr_regs; c->prog_data.total_grf = i; } @@ -69,12 +71,22 @@ static void brw_gs_emit_vue(struct brw_gs_compile *c, GLuint header) { struct brw_compile *p = &c->func; + struct intel_context *intel = &c->func.brw->intel; GLboolean allocate = !last; + struct brw_reg temp; + + if (intel->gen < 6) + temp = c->reg.R0; + else { + temp = c->reg.temp; + brw_MOV(p, retype(temp, BRW_REGISTER_TYPE_UD), + retype(c->reg.R0, BRW_REGISTER_TYPE_UD)); + } /* Overwrite PrimType and PrimStart in the message header, for * each vertex in turn: */ - brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header)); + brw_MOV(p, get_element_ud(temp, 2), brw_imm_ud(header)); /* Copy the vertex from vertn into m1..mN+1: */ @@ -87,9 +99,9 @@ static void brw_gs_emit_vue(struct brw_gs_compile *c, * allocated each time. */ brw_urb_WRITE(p, - allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), + allocate ? temp : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), 0, - c->reg.R0, + temp, allocate, 1, /* used */ c->nr_regs + 1, /* msg length */ @@ -98,19 +110,39 @@ static void brw_gs_emit_vue(struct brw_gs_compile *c, 1, /* writes_complete */ 0, /* urb offset */ BRW_URB_SWIZZLE_NONE); + + if (intel->gen >= 6 && allocate) + brw_MOV(p, get_element_ud(c->reg.R0, 0), get_element_ud(temp, 0)); } static void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim) { struct brw_compile *p = &c->func; - brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim)); - brw_ff_sync(p, - c->reg.R0, - 0, - c->reg.R0, - 1, /* allocate */ - 1, /* response length */ - 0 /* eot */); + struct intel_context *intel = &c->func.brw->intel; + + if (intel->gen < 6) { + brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim)); + brw_ff_sync(p, + c->reg.R0, + 0, + c->reg.R0, + 1, /* allocate */ + 1, /* response length */ + 0 /* eot */); + } else { + brw_MOV(p, retype(c->reg.temp, BRW_REGISTER_TYPE_UD), + retype(c->reg.R0, BRW_REGISTER_TYPE_UD)); + brw_MOV(p, get_element_ud(c->reg.temp, 1), brw_imm_ud(num_prim)); + brw_ff_sync(p, + c->reg.temp, + 0, + c->reg.temp, + 1, /* allocate */ + 1, /* response length */ + 0 /* eot */); + brw_MOV(p, get_element_ud(c->reg.R0, 0), + get_element_ud(c->reg.temp, 0)); + } } |