drm/i915/bdw: Render ring flushing
authorBen Widawsky <benjamin.widawsky@intel.com>
Sun, 3 Nov 2013 04:07:27 +0000 (21:07 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 8 Nov 2013 17:09:49 +0000 (18:09 +0100)
PIPE_CONTROL added the high address dword. I'm not sure how the
simulator let me get away with this. I've explicitly left out all the
workarounds from Gen7 because in the minimal digging that I did, most
don't seem necessary, and the simulator doesn't complain without them

Note that BLT and BSD ring commands had already been updated previously.
Just render/pipe_control should have been broken.

v2: Squash in a fixup from Ville to follow the recent IVB PIPE_CONTROL
updates: "BDW uses the IVB PIPE_CONTROL style for specifying GTT vs.
PPGTT for the PIPE_CONTROL QW/DW write."

v3: Rebase on top of Chris' cleanup to have an explicit ring->scratch
buffer object instead of an opaque ring->private where everyone stores
the same stuff inside.

Reported-by: Damien Lespiau <damien.lespiau@intel.com>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net> (for the fixup)
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net> (v1)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_ringbuffer.c

index db086f4..08744aa 100644 (file)
@@ -360,6 +360,47 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring,
        return 0;
 }
 
+static int
+gen8_render_ring_flush(struct intel_ring_buffer *ring,
+                      u32 invalidate_domains, u32 flush_domains)
+{
+       u32 flags = 0;
+       u32 scratch_addr = ring->scratch.gtt_offset + 128;
+       int ret;
+
+       flags |= PIPE_CONTROL_CS_STALL;
+
+       if (flush_domains) {
+               flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+               flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
+       }
+       if (invalidate_domains) {
+               flags |= PIPE_CONTROL_TLB_INVALIDATE;
+               flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
+               flags |= PIPE_CONTROL_QW_WRITE;
+               flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
+       }
+
+       ret = intel_ring_begin(ring, 6);
+       if (ret)
+               return ret;
+
+       intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
+       intel_ring_emit(ring, flags);
+       intel_ring_emit(ring, scratch_addr);
+       intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, 0);
+       intel_ring_emit(ring, 0);
+       intel_ring_advance(ring);
+
+       return 0;
+
+}
+
 static void ring_write_tail(struct intel_ring_buffer *ring,
                            u32 value)
 {
@@ -1817,6 +1858,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
                if (INTEL_INFO(dev)->gen == 6)
                        ring->flush = gen6_render_ring_flush;
                if (INTEL_INFO(dev)->gen >= 8) {
+                       ring->flush = gen8_render_ring_flush;
                        ring->irq_get = gen8_ring_get_irq;
                        ring->irq_put = gen8_ring_put_irq;
                } else {