diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-20 11:33:05 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-20 11:37:01 +0000 |
commit | 0286ddbd67d3b2585ffa3deccb7eeb674cd7a3e0 (patch) | |
tree | 12c7f4617258fd8b348ba01a8b22fd875751ae58 | |
parent | a0c4024e32ccab70e7f7893896d30c80ad9f4240 (diff) |
sna/gen6: Cleanup non-pipelined w/a
Move the workaround CS stall into the emit drawrect which is the only
non-pipelined op we emit. This removes the split between deciding
whether we will emit a drawrect and actual emission.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/gen6_render.c | 67 |
1 files changed, 29 insertions, 38 deletions
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index cf747db5..60b04465 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -699,22 +699,39 @@ gen6_emit_binding_table(struct sna *sna, uint16_t offset) } static bool -gen6_need_drawing_rectangle(struct sna *sna, +gen6_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op) { uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1); uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x; - return (sna->render_state.gen6.drawrect_limit != limit || - sna->render_state.gen6.drawrect_offset != offset); -} + if (sna->render_state.gen6.drawrect_limit == limit && + sna->render_state.gen6.drawrect_offset == offset) + return false; -static void -gen6_emit_drawing_rectangle(struct sna *sna, - const struct sna_composite_op *op) -{ - uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1); - uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x; + /* [DevSNB-C+{W/A}] Before any depth stall flush (including those + * produced by non-pipelined state commands), software needs to first + * send a PIPE_CONTROL with no bits set except Post-Sync Operation != + * 0. + * + * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent + * BEFORE the pipe-control with a post-sync op and no write-cache + * flushes. + */ + OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2)); + OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL | + GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD); + OUT_BATCH(0); + OUT_BATCH(0); + + OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2)); + OUT_BATCH(GEN6_PIPE_CONTROL_WRITE_TIME); + OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, + sna->render_state.gen6.general_bo, + I915_GEM_DOMAIN_INSTRUCTION << 16 | + I915_GEM_DOMAIN_INSTRUCTION, + 64)); + OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); OUT_BATCH(0); @@ -723,6 +740,7 @@ gen6_emit_drawing_rectangle(struct sna *sna, sna->render_state.gen6.drawrect_offset = offset; sna->render_state.gen6.drawrect_limit = limit; + return true; } static void @@ -834,35 +852,8 @@ gen6_emit_state(struct sna *sna, op->u.gen6.nr_inputs); gen6_emit_vertex_elements(sna, op); need_stall = gen6_emit_binding_table(sna, wm_binding_table); - - /* [DevSNB-C+{W/A}] Before any depth stall flush (including those - * produced by non-pipelined state commands), software needs to first - * send a PIPE_CONTROL with no bits set except Post-Sync Operation != - * 0. - * - * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent - * BEFORE the pipe-control with a post-sync op and no write-cache - * flushes. - */ - if (gen6_need_drawing_rectangle(sna, op)) { - OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2)); - OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL | - GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD); - OUT_BATCH(0); - OUT_BATCH(0); - - OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2)); - OUT_BATCH(GEN6_PIPE_CONTROL_WRITE_TIME); - OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, - sna->render_state.gen6.general_bo, - I915_GEM_DOMAIN_INSTRUCTION << 16 | - I915_GEM_DOMAIN_INSTRUCTION, - 64)); - OUT_BATCH(0); - - gen6_emit_drawing_rectangle(sna, op); + if (gen6_emit_drawing_rectangle(sna, op)) need_stall = false; - } if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { gen6_emit_flush(sna); kgem_clear_dirty(&sna->kgem); |