summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-06-05 15:33:27 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-06-05 15:40:00 +0100
commit407257570fea1c6456fda47c9fab36c39f169c2b (patch)
treef3522ec783d9854f0926c93673bc7f34070e6829
parent73167711226f430cc9ef4c27f267655d0edf4622 (diff)
sna/gen6: Flush the pipeline before effecting a change of blend modes
... also make sure that we flush if we change the blend mode for the CA pass. Reported-by: Ivan Bulatovic <combuster@archlinux.us> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=37946 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen6_render.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 3f1749fa..56aaadcc 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -51,8 +51,6 @@
#define NDEBUG 1
#endif
-#define ALWAYS_EMIT_DRAWRECT 1
-
#define NO_COMPOSITE 0
#define NO_COPY 0
#define NO_COPY_BOXES 0
@@ -583,13 +581,13 @@ gen6_emit_invariant(struct sna *sna)
sna->render_state.gen6.needs_invariant = FALSE;
}
-static void
+static bool
gen6_emit_cc(struct sna *sna, uint32_t blend_offset)
{
struct gen6_render_state *render = &sna->render_state.gen6;
if (render->blend == blend_offset)
- return;
+ return false;
OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2));
OUT_BATCH((render->cc_blend + blend_offset) | 1);
@@ -602,6 +600,7 @@ gen6_emit_cc(struct sna *sna, uint32_t blend_offset)
}
render->blend = blend_offset;
+ return true;
}
static void
@@ -812,13 +811,14 @@ gen6_emit_state(struct sna *sna,
uint16_t wm_binding_table)
{
- bool need_flush =
- (sna->kgem.batch[sna->kgem.nbatch-1] & (0xff<<23)) != MI_FLUSH;
+ bool flushed =
+ (sna->kgem.batch[sna->kgem.nbatch-1] & (0xff<<23)) == MI_FLUSH;
+ bool need_flush;
- gen6_emit_cc(sna,
- gen6_get_blend(op->op,
- op->has_component_alpha,
- op->dst.format));
+ need_flush = gen6_emit_cc(sna,
+ gen6_get_blend(op->op,
+ op->has_component_alpha,
+ op->dst.format));
DBG(("%s: sampler src=(%d, %d), mask=(%d, %d), offset=%d\n",
__FUNCTION__,
@@ -841,14 +841,15 @@ gen6_emit_state(struct sna *sna,
gen6_emit_vertex_elements(sna, op);
/* XXX updating the binding table requires a non-pipelined cmd? */
- need_flush &= gen6_emit_binding_table(sna, wm_binding_table);
- gen6_emit_drawing_rectangle(sna, op, need_flush);
+ need_flush |= gen6_emit_binding_table(sna, wm_binding_table);
+ gen6_emit_drawing_rectangle(sna, op, need_flush & !flushed);
}
static void gen6_magic_ca_pass(struct sna *sna,
const struct sna_composite_op *op)
{
struct gen6_render_state *state = &sna->render_state.gen6;
+ bool need_flush;
if (!op->need_magic_ca_pass)
return;
@@ -856,14 +857,21 @@ static void gen6_magic_ca_pass(struct sna *sna,
DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__,
sna->render.vertex_start, sna->render.vertex_index));
- gen6_emit_cc(sna,
- gen6_get_blend(PictOpAdd, TRUE, op->dst.format));
+ need_flush =
+ gen6_emit_cc(sna,
+ gen6_get_blend(PictOpAdd, TRUE, op->dst.format));
gen6_emit_wm(sna,
gen6_choose_composite_kernel(PictOpAdd,
TRUE, TRUE,
op->is_affine),
3, 2);
+ /* XXX We apparently need a non-pipelined op to flush the
+ * pipeline before changing blend state.
+ */
+ if (need_flush)
+ OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH);
+
OUT_BATCH(GEN6_3DPRIMITIVE |
GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
_3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |