* [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define.
@ 2011-10-11 21:41 Daniel Vetter
2011-10-11 21:41 ` [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse Daniel Vetter
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Daniel Vetter @ 2011-10-11 21:41 UTC (permalink / raw)
To: intel-gfx; +Cc: Daniel Vetter
From: Kenneth Graunke <kenneth@whitecape.org>
Not all PIPE_CONTROLs have a length of 2, so remove it from the #define
and make each invocation specify the desired length.
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
[danvet: implement style suggestion from Ben Widawsdy]
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/i915_reg.h | 2 +-
drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d228fab..c4dd824 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -242,7 +242,7 @@
#define ASYNC_FLIP (1<<22)
#define DISPLAY_PLANE_A (0<<20)
#define DISPLAY_PLANE_B (1<<20)
-#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
+#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2))
#define PIPE_CONTROL_QW_WRITE (1<<14)
#define PIPE_CONTROL_DEPTH_STALL (1<<13)
#define PIPE_CONTROL_WC_FLUSH (1<<12)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index a056ecf..ed7bf40 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -438,8 +438,8 @@ gen6_blt_ring_sync_to(struct intel_ring_buffer *waiter,
#define PIPE_CONTROL_FLUSH(ring__, addr__) \
do { \
- intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \
- PIPE_CONTROL_DEPTH_STALL | 2); \
+ intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | \
+ PIPE_CONTROL_DEPTH_STALL); \
intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \
intel_ring_emit(ring__, 0); \
intel_ring_emit(ring__, 0); \
@@ -467,7 +467,7 @@ pc_render_add_request(struct intel_ring_buffer *ring,
if (ret)
return ret;
- intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+ intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE |
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
intel_ring_emit(ring, seqno);
@@ -483,7 +483,7 @@ pc_render_add_request(struct intel_ring_buffer *ring,
PIPE_CONTROL_FLUSH(ring, scratch_addr);
scratch_addr += 128;
PIPE_CONTROL_FLUSH(ring, scratch_addr);
- intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+ intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE |
PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
PIPE_CONTROL_NOTIFY);
intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
--
1.7.6.4
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse. 2011-10-11 21:41 [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define Daniel Vetter @ 2011-10-11 21:41 ` Daniel Vetter 2011-10-11 23:51 ` Ben Widawsky 2011-10-11 21:41 ` [PATCH 3/3] drm/i915: Use PIPE_CONTROL for flushing on gen6+ Daniel Vetter 2011-10-11 23:11 ` [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define Kenneth Graunke 2 siblings, 1 reply; 9+ messages in thread From: Daniel Vetter @ 2011-10-11 21:41 UTC (permalink / raw) To: intel-gfx; +Cc: Daniel Vetter From: Kenneth Graunke <kenneth@whitecape.org> "STALL_AT_SCOREBOARD" is much clearer than "STALL_EN" now that there are several different kinds of stalls. Also, "INSTRUCTION_CACHE_INVALIDATE" is a lot easier to understand at a glance than the terse "IS_FLUSH." Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> [danvet: use INVALIDATE for ro cache flags for more consistency] Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch> --- drivers/gpu/drm/i915/i915_reg.h | 16 ++++++++-------- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c4dd824..7f496a1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -243,15 +243,15 @@ #define DISPLAY_PLANE_A (0<<20) #define DISPLAY_PLANE_B (1<<20) #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) -#define PIPE_CONTROL_QW_WRITE (1<<14) -#define PIPE_CONTROL_DEPTH_STALL (1<<13) -#define PIPE_CONTROL_WC_FLUSH (1<<12) -#define PIPE_CONTROL_IS_FLUSH (1<<11) /* MBZ on Ironlake */ -#define PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */ -#define PIPE_CONTROL_ISP_DIS (1<<9) -#define PIPE_CONTROL_NOTIFY (1<<8) +#define PIPE_CONTROL_QW_WRITE (1<<14) +#define PIPE_CONTROL_DEPTH_STALL (1<<13) +#define PIPE_CONTROL_WRITE_FLUSH (1<<12) +#define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on Ironlake */ +#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */ +#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9) +#define PIPE_CONTROL_NOTIFY (1<<8) +#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1) #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ -#define PIPE_CONTROL_STALL_EN (1<<1) /* in addr word, Ironlake+ only */ /* diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ed7bf40..2f3c3e1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -468,7 +468,8 @@ pc_render_add_request(struct intel_ring_buffer *ring, return ret; intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); + PIPE_CONTROL_WRITE_FLUSH | + PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); intel_ring_emit(ring, seqno); intel_ring_emit(ring, 0); @@ -484,7 +485,8 @@ pc_render_add_request(struct intel_ring_buffer *ring, scratch_addr += 128; PIPE_CONTROL_FLUSH(ring, scratch_addr); intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | + PIPE_CONTROL_WRITE_FLUSH | + PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | PIPE_CONTROL_NOTIFY); intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); intel_ring_emit(ring, seqno); -- 1.7.6.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse. 2011-10-11 21:41 ` [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse Daniel Vetter @ 2011-10-11 23:51 ` Ben Widawsky 2011-10-15 14:01 ` Daniel Vetter 0 siblings, 1 reply; 9+ messages in thread From: Ben Widawsky @ 2011-10-11 23:51 UTC (permalink / raw) To: Daniel Vetter; +Cc: intel-gfx On Tue, 11 Oct 2011 23:41:09 +0200 Daniel Vetter <daniel.vetter@ffwll.ch> wrote: > From: Kenneth Graunke <kenneth@whitecape.org> > > "STALL_AT_SCOREBOARD" is much clearer than "STALL_EN" now that there are > several different kinds of stalls. Also, "INSTRUCTION_CACHE_INVALIDATE" > is a lot easier to understand at a glance than the terse "IS_FLUSH." > > Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> > [danvet: use INVALIDATE for ro cache flags for more consistency] > Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch> > --- > drivers/gpu/drm/i915/i915_reg.h | 16 ++++++++-------- > drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++++-- > 2 files changed, 12 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index c4dd824..7f496a1 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -243,15 +243,15 @@ > #define DISPLAY_PLANE_A (0<<20) > #define DISPLAY_PLANE_B (1<<20) > #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) > -#define PIPE_CONTROL_QW_WRITE (1<<14) > -#define PIPE_CONTROL_DEPTH_STALL (1<<13) > -#define PIPE_CONTROL_WC_FLUSH (1<<12) > -#define PIPE_CONTROL_IS_FLUSH (1<<11) /* MBZ on Ironlake */ > -#define PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */ > -#define PIPE_CONTROL_ISP_DIS (1<<9) > -#define PIPE_CONTROL_NOTIFY (1<<8) > +#define PIPE_CONTROL_QW_WRITE (1<<14) > +#define PIPE_CONTROL_DEPTH_STALL (1<<13) > +#define PIPE_CONTROL_WRITE_FLUSH (1<<12) > +#define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on Ironlake */ > +#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */ > +#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9) > +#define PIPE_CONTROL_NOTIFY (1<<8) > +#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1) > #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ > -#define PIPE_CONTROL_STALL_EN (1<<1) /* in addr word, Ironlake+ only */ > > I thought we all agreed that "PIPE_CONTROL_WRITE_FLUSH" doesn't make sense for Gen6? Or was that just me agreeing with myself? ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse. 2011-10-11 23:51 ` Ben Widawsky @ 2011-10-15 14:01 ` Daniel Vetter 2011-10-15 19:26 ` Ben Widawsky 0 siblings, 1 reply; 9+ messages in thread From: Daniel Vetter @ 2011-10-15 14:01 UTC (permalink / raw) To: Ben Widawsky; +Cc: Daniel Vetter, intel-gfx On Tue, Oct 11, 2011 at 04:51:16PM -0700, Ben Widawsky wrote: > I thought we all agreed that "PIPE_CONTROL_WRITE_FLUSH" doesn't make > sense for Gen6? Or was that just me agreeing with myself? I couldn't find any comment of yours to that effect ... :p You'd be much happier if I add a RENDER_CACHE_FLUSH for gen6+? Cheers, Daniel -- Daniel Vetter Mail: daniel@ffwll.ch Mobile: +41 (0)79 365 57 48 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse. 2011-10-15 14:01 ` Daniel Vetter @ 2011-10-15 19:26 ` Ben Widawsky 0 siblings, 0 replies; 9+ messages in thread From: Ben Widawsky @ 2011-10-15 19:26 UTC (permalink / raw) To: Daniel Vetter; +Cc: Daniel Vetter, intel-gfx On Sat, 15 Oct 2011 16:01:17 +0200 Daniel Vetter <daniel@ffwll.ch> wrote: > On Tue, Oct 11, 2011 at 04:51:16PM -0700, Ben Widawsky wrote: > > I thought we all agreed that "PIPE_CONTROL_WRITE_FLUSH" doesn't make > > sense for Gen6? Or was that just me agreeing with myself? > > I couldn't find any comment of yours to that effect ... :p You'd be much > happier if I add a RENDER_CACHE_FLUSH for gen6+? > > Cheers, Daniel I really want to make these things match the docs as closely as possible. Especially PIPE_CONTROL which I know I will refer to over and over. Like I said, r-b from me either way, but if you redo the series anyway for some reason, I would prefer that. Ben ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] drm/i915: Use PIPE_CONTROL for flushing on gen6+. 2011-10-11 21:41 [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define Daniel Vetter 2011-10-11 21:41 ` [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse Daniel Vetter @ 2011-10-11 21:41 ` Daniel Vetter 2011-10-16 8:23 ` [PATCH] " Daniel Vetter 2011-10-11 23:11 ` [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define Kenneth Graunke 2 siblings, 1 reply; 9+ messages in thread From: Daniel Vetter @ 2011-10-11 21:41 UTC (permalink / raw) To: intel-gfx; +Cc: Daniel Vetter From: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> [danvet: this seems to fix cairo-perf-trace hangs on my snb] Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch> --- drivers/gpu/drm/i915/i915_reg.h | 5 + drivers/gpu/drm/i915/intel_ringbuffer.c | 136 ++++++++++++++++++++++++++++--- 2 files changed, 129 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7f496a1..eca64e1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -243,6 +243,7 @@ #define DISPLAY_PLANE_A (0<<20) #define DISPLAY_PLANE_B (1<<20) #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) +#define PIPE_CONTROL_CS_STALL (1<<20) #define PIPE_CONTROL_QW_WRITE (1<<14) #define PIPE_CONTROL_DEPTH_STALL (1<<13) #define PIPE_CONTROL_WRITE_FLUSH (1<<12) @@ -250,7 +251,11 @@ #define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */ #define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9) #define PIPE_CONTROL_NOTIFY (1<<8) +#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4) +#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3) +#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2) #define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1) +#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0) #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2f3c3e1..6f71cff 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -34,6 +34,16 @@ #include "i915_trace.h" #include "intel_drv.h" +/* + * 965+ support PIPE_CONTROL commands, which provide finer grained control + * over cache flushing. + */ +struct pipe_control { + struct drm_i915_gem_object *obj; + volatile u32 *cpu_page; + u32 gtt_offset; +}; + static inline int ring_space(struct intel_ring_buffer *ring) { int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); @@ -123,6 +133,118 @@ render_ring_flush(struct intel_ring_buffer *ring, return 0; } +/** + * Emits a PIPE_CONTROL with a non-zero post-sync operation, for + * implementing two workarounds on gen6. From section 1.4.7.1 + * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1: + * + * [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}]: Before a PIPE_CONTROL with Write Cache Flush Enable + * =1, a PIPE_CONTROL with any non-zero post-sync-op is required. + * + * And the workaround for these two requires this workaround first: + * + * [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. + * + * And this last workaround is tricky because of the requirements on + * that bit. From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM + * volume 2 part 1: + * + * "1 of the following must also be set: + * - Render Target Cache Flush Enable ([12] of DW1) + * - Depth Cache Flush Enable ([0] of DW1) + * - Stall at Pixel Scoreboard ([1] of DW1) + * - Depth Stall ([13] of DW1) + * - Post-Sync Operation ([13] of DW1) + * - Notify Enable ([8] of DW1)" + * + * The cache flushes require the workaround flush that triggered this + * one, so we can't use it. Depth stall would trigger the same. + * Post-sync nonzero is what triggered this second workaround, so we + * can't use that one either. Notify enable is IRQs, which aren't + * really our business. That leaves only stall at scoreboard. + */ +static int +intel_emit_post_sync_nonzero_flush(struct intel_ring_buffer *ring) +{ + struct pipe_control *pc = ring->private; + u32 scratch_addr = pc->gtt_offset + 128; + int ret; + + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); + intel_ring_emit(ring, PIPE_CONTROL_CS_STALL | + PIPE_CONTROL_STALL_AT_SCOREBOARD); + intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ + intel_ring_emit(ring, 0); /* low dword */ + intel_ring_emit(ring, 0); /* high dword */ + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); + intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE); + intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + return 0; +} + +static int +gen6_render_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, u32 flush_domains) +{ + u32 flags = 0; + struct pipe_control *pc = ring->private; + u32 scratch_addr = pc->gtt_offset + 128; + int ret; + + /* Force SNB workarounds for PIPE_CONTROL flushes */ + intel_emit_post_sync_nonzero_flush(ring); + + /* Just flush everything. Experiments have shown that reducing the + * number of bits based on the write domains has little performance + * impact. + */ + flags |= PIPE_CONTROL_WRITE_FLUSH; + flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; + flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); + intel_ring_emit(ring, flags); + intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, 0); /* lower dword */ + intel_ring_emit(ring, 0); /* uppwer dword */ + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + return 0; +} + static void ring_write_tail(struct intel_ring_buffer *ring, u32 value) { @@ -206,16 +328,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) return 0; } -/* - * 965+ support PIPE_CONTROL commands, which provide finer grained control - * over cache flushing. - */ -struct pipe_control { - struct drm_i915_gem_object *obj; - volatile u32 *cpu_page; - u32 gtt_offset; -}; - static int init_pipe_control(struct intel_ring_buffer *ring) { @@ -296,8 +408,7 @@ static int init_render_ring(struct intel_ring_buffer *ring) GFX_MODE_ENABLE(GFX_REPLAY_MODE)); } - if (INTEL_INFO(dev)->gen >= 6) { - } else if (IS_GEN5(dev)) { + if (INTEL_INFO(dev)->gen >= 5) { ret = init_pipe_control(ring); if (ret) return ret; @@ -1369,6 +1480,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) *ring = render_ring; if (INTEL_INFO(dev)->gen >= 6) { ring->add_request = gen6_add_request; + ring->flush = gen6_render_ring_flush; ring->irq_get = gen6_render_ring_get_irq; ring->irq_put = gen6_render_ring_put_irq; } else if (IS_GEN5(dev)) { -- 1.7.6.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH] drm/i915: Use PIPE_CONTROL for flushing on gen6+. 2011-10-11 21:41 ` [PATCH 3/3] drm/i915: Use PIPE_CONTROL for flushing on gen6+ Daniel Vetter @ 2011-10-16 8:23 ` Daniel Vetter 2011-10-17 1:27 ` Ben Widawsky 0 siblings, 1 reply; 9+ messages in thread From: Daniel Vetter @ 2011-10-16 8:23 UTC (permalink / raw) To: intel-gfx; +Cc: Daniel Vetter, Ben Widawsky From: Jesse Barnes <jbarnes@virtuousgeek.org> v2 by danvet: Use a new flag to flush the render target cache on gen6+ (hw reuses the old write flush bit), as suggested by Ben Widawsdy. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> [danvet: this seems to fix cairo-perf-trace hangs on my snb] Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch> --- drivers/gpu/drm/i915/i915_reg.h | 6 ++ drivers/gpu/drm/i915/intel_ringbuffer.c | 136 ++++++++++++++++++++++++++++--- 2 files changed, 130 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7f496a1..a432b06 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -243,14 +243,20 @@ #define DISPLAY_PLANE_A (0<<20) #define DISPLAY_PLANE_B (1<<20) #define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) +#define PIPE_CONTROL_CS_STALL (1<<20) #define PIPE_CONTROL_QW_WRITE (1<<14) #define PIPE_CONTROL_DEPTH_STALL (1<<13) #define PIPE_CONTROL_WRITE_FLUSH (1<<12) +#define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */ #define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on Ironlake */ #define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */ #define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9) #define PIPE_CONTROL_NOTIFY (1<<8) +#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4) +#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3) +#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2) #define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1) +#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0) #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2f3c3e1..3c30dba 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -34,6 +34,16 @@ #include "i915_trace.h" #include "intel_drv.h" +/* + * 965+ support PIPE_CONTROL commands, which provide finer grained control + * over cache flushing. + */ +struct pipe_control { + struct drm_i915_gem_object *obj; + volatile u32 *cpu_page; + u32 gtt_offset; +}; + static inline int ring_space(struct intel_ring_buffer *ring) { int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); @@ -123,6 +133,118 @@ render_ring_flush(struct intel_ring_buffer *ring, return 0; } +/** + * Emits a PIPE_CONTROL with a non-zero post-sync operation, for + * implementing two workarounds on gen6. From section 1.4.7.1 + * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1: + * + * [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}]: Before a PIPE_CONTROL with Write Cache Flush Enable + * =1, a PIPE_CONTROL with any non-zero post-sync-op is required. + * + * And the workaround for these two requires this workaround first: + * + * [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. + * + * And this last workaround is tricky because of the requirements on + * that bit. From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM + * volume 2 part 1: + * + * "1 of the following must also be set: + * - Render Target Cache Flush Enable ([12] of DW1) + * - Depth Cache Flush Enable ([0] of DW1) + * - Stall at Pixel Scoreboard ([1] of DW1) + * - Depth Stall ([13] of DW1) + * - Post-Sync Operation ([13] of DW1) + * - Notify Enable ([8] of DW1)" + * + * The cache flushes require the workaround flush that triggered this + * one, so we can't use it. Depth stall would trigger the same. + * Post-sync nonzero is what triggered this second workaround, so we + * can't use that one either. Notify enable is IRQs, which aren't + * really our business. That leaves only stall at scoreboard. + */ +static int +intel_emit_post_sync_nonzero_flush(struct intel_ring_buffer *ring) +{ + struct pipe_control *pc = ring->private; + u32 scratch_addr = pc->gtt_offset + 128; + int ret; + + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); + intel_ring_emit(ring, PIPE_CONTROL_CS_STALL | + PIPE_CONTROL_STALL_AT_SCOREBOARD); + intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ + intel_ring_emit(ring, 0); /* low dword */ + intel_ring_emit(ring, 0); /* high dword */ + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); + intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE); + intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + return 0; +} + +static int +gen6_render_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, u32 flush_domains) +{ + u32 flags = 0; + struct pipe_control *pc = ring->private; + u32 scratch_addr = pc->gtt_offset + 128; + int ret; + + /* Force SNB workarounds for PIPE_CONTROL flushes */ + intel_emit_post_sync_nonzero_flush(ring); + + /* Just flush everything. Experiments have shown that reducing the + * number of bits based on the write domains has little performance + * impact. + */ + flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; + flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; + flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); + intel_ring_emit(ring, flags); + intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, 0); /* lower dword */ + intel_ring_emit(ring, 0); /* uppwer dword */ + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + return 0; +} + static void ring_write_tail(struct intel_ring_buffer *ring, u32 value) { @@ -206,16 +328,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) return 0; } -/* - * 965+ support PIPE_CONTROL commands, which provide finer grained control - * over cache flushing. - */ -struct pipe_control { - struct drm_i915_gem_object *obj; - volatile u32 *cpu_page; - u32 gtt_offset; -}; - static int init_pipe_control(struct intel_ring_buffer *ring) { @@ -296,8 +408,7 @@ static int init_render_ring(struct intel_ring_buffer *ring) GFX_MODE_ENABLE(GFX_REPLAY_MODE)); } - if (INTEL_INFO(dev)->gen >= 6) { - } else if (IS_GEN5(dev)) { + if (INTEL_INFO(dev)->gen >= 5) { ret = init_pipe_control(ring); if (ret) return ret; @@ -1369,6 +1480,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) *ring = render_ring; if (INTEL_INFO(dev)->gen >= 6) { ring->add_request = gen6_add_request; + ring->flush = gen6_render_ring_flush; ring->irq_get = gen6_render_ring_get_irq; ring->irq_put = gen6_render_ring_put_irq; } else if (IS_GEN5(dev)) { -- 1.7.6.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] drm/i915: Use PIPE_CONTROL for flushing on gen6+. 2011-10-16 8:23 ` [PATCH] " Daniel Vetter @ 2011-10-17 1:27 ` Ben Widawsky 0 siblings, 0 replies; 9+ messages in thread From: Ben Widawsky @ 2011-10-17 1:27 UTC (permalink / raw) To: Daniel Vetter; +Cc: intel-gfx On Sun, 16 Oct 2011 10:23:31 +0200 Daniel Vetter <daniel.vetter@ffwll.ch> wrote: > From: Jesse Barnes <jbarnes@virtuousgeek.org> > > v2 by danvet: Use a new flag to flush the render target cache on gen6+ > (hw reuses the old write flush bit), as suggested by Ben Widawsdy. > > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> > [danvet: this seems to fix cairo-perf-trace hangs on my snb] > Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch> > --- Reviewed-by: Ben Widawsky <ben@bwidawsk.net> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define. 2011-10-11 21:41 [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define Daniel Vetter 2011-10-11 21:41 ` [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse Daniel Vetter 2011-10-11 21:41 ` [PATCH 3/3] drm/i915: Use PIPE_CONTROL for flushing on gen6+ Daniel Vetter @ 2011-10-11 23:11 ` Kenneth Graunke 2 siblings, 0 replies; 9+ messages in thread From: Kenneth Graunke @ 2011-10-11 23:11 UTC (permalink / raw) To: Daniel Vetter; +Cc: intel-gfx The series looks good, Daniel. Thanks for cleaning it up! ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-10-17 1:28 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-10-11 21:41 [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define Daniel Vetter 2011-10-11 21:41 ` [PATCH 2/3] drm/i915: Rename PIPE_CONTROL bit defines to be less terse Daniel Vetter 2011-10-11 23:51 ` Ben Widawsky 2011-10-15 14:01 ` Daniel Vetter 2011-10-15 19:26 ` Ben Widawsky 2011-10-11 21:41 ` [PATCH 3/3] drm/i915: Use PIPE_CONTROL for flushing on gen6+ Daniel Vetter 2011-10-16 8:23 ` [PATCH] " Daniel Vetter 2011-10-17 1:27 ` Ben Widawsky 2011-10-11 23:11 ` [PATCH 1/3] drm/i915: Remove implied length of 2 from GFX_OP_PIPE_CONTROL #define Kenneth Graunke
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.