drm/i915: Record space required for breadcrumb emission
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 28 Oct 2016 12:58:51 +0000 (13:58 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 28 Oct 2016 19:53:53 +0000 (20:53 +0100)
In the next patch, we will use deferred breadcrumb emission. That requires
reserving sufficient space in the ringbuffer to emit the breadcrumb, which
first requires us to know how large the breadcrumb is.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161028125858.23563-28-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index a626b263872272b78052ef9c0fa693c100689767..be9e23b32e4a3b1fd91abf8ed98715c6d8ac0d13 100644 (file)
@@ -434,6 +434,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
         * away, e.g. because a GPU scheduler has deferred it.
         */
        req->reserved_space = MIN_SPACE_FOR_ADD_REQUEST;
+       GEM_BUG_ON(req->reserved_space < engine->emit_breadcrumb_sz);
 
        if (i915.enable_execlists)
                ret = intel_logical_ring_alloc_request_extras(req);
index 57dba458f1853b0248a1ea7577d9a51b8d8bea7f..8229baebb2b3e95ccb5ad32e76dd99bc3be31f66 100644 (file)
@@ -1590,6 +1590,8 @@ static int gen8_emit_breadcrumb(struct drm_i915_gem_request *request)
        return intel_logical_ring_advance(request);
 }
 
+static const int gen8_emit_breadcrumb_sz = 6 + WA_TAIL_DWORDS;
+
 static int gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request)
 {
        struct intel_ring *ring = request->ring;
@@ -1621,6 +1623,8 @@ static int gen8_emit_breadcrumb_render(struct drm_i915_gem_request *request)
        return intel_logical_ring_advance(request);
 }
 
+static const int gen8_emit_breadcrumb_render_sz = 8 + WA_TAIL_DWORDS;
+
 static int gen8_init_rcs_context(struct drm_i915_gem_request *req)
 {
        int ret;
@@ -1695,6 +1699,7 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
        engine->reset_hw = reset_common_ring;
        engine->emit_flush = gen8_emit_flush;
        engine->emit_breadcrumb = gen8_emit_breadcrumb;
+       engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_sz;
        engine->submit_request = execlists_submit_request;
 
        engine->irq_enable = gen8_logical_ring_enable_irq;
@@ -1817,6 +1822,7 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
        engine->init_context = gen8_init_rcs_context;
        engine->emit_flush = gen8_emit_flush_render;
        engine->emit_breadcrumb = gen8_emit_breadcrumb_render;
+       engine->emit_breadcrumb_sz = gen8_emit_breadcrumb_render_sz;
 
        ret = intel_engine_create_scratch(engine, 4096);
        if (ret)
index 54c3981cf71680d548efd3ae5b0f7e13fac9d63d..ae9cf6bb4def476c0d27c5985d7f6a8119304fc8 100644 (file)
@@ -1348,6 +1348,8 @@ static int i9xx_emit_breadcrumb(struct drm_i915_gem_request *req)
        return 0;
 }
 
+static const int i9xx_emit_breadcrumb_sz = 4;
+
 /**
  * gen6_sema_emit_breadcrumb - Update the semaphore mailbox registers
  *
@@ -1401,6 +1403,8 @@ static int gen8_render_emit_breadcrumb(struct drm_i915_gem_request *req)
        return 0;
 }
 
+static const int gen8_render_emit_breadcrumb_sz = 8;
+
 /**
  * intel_ring_sync - sync the waiter to the signaller on seqno
  *
@@ -2638,8 +2642,21 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
        engine->reset_hw = reset_ring_common;
 
        engine->emit_breadcrumb = i9xx_emit_breadcrumb;
-       if (i915.semaphores)
+       engine->emit_breadcrumb_sz = i9xx_emit_breadcrumb_sz;
+       if (i915.semaphores) {
+               int num_rings;
+
                engine->emit_breadcrumb = gen6_sema_emit_breadcrumb;
+
+               num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+               if (INTEL_GEN(dev_priv) >= 8) {
+                       engine->emit_breadcrumb_sz += num_rings * 6;
+               } else {
+                       engine->emit_breadcrumb_sz += num_rings * 3;
+                       if (num_rings & 1)
+                               engine->emit_breadcrumb_sz++;
+               }
+       }
        engine->submit_request = i9xx_submit_request;
 
        if (INTEL_GEN(dev_priv) >= 8)
@@ -2667,9 +2684,17 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine)
        if (INTEL_GEN(dev_priv) >= 8) {
                engine->init_context = intel_rcs_ctx_init;
                engine->emit_breadcrumb = gen8_render_emit_breadcrumb;
+               engine->emit_breadcrumb_sz = gen8_render_emit_breadcrumb_sz;
                engine->emit_flush = gen8_render_ring_flush;
-               if (i915.semaphores)
+               if (i915.semaphores) {
+                       int num_rings;
+
                        engine->semaphore.signal = gen8_rcs_signal;
+
+                       num_rings =
+                               hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+                       engine->emit_breadcrumb_sz += num_rings * 6;
+               }
        } else if (INTEL_GEN(dev_priv) >= 6) {
                engine->init_context = intel_rcs_ctx_init;
                engine->emit_flush = gen7_render_ring_flush;
index a5ced1649ecd1f6124d7de2ff490c703ef695e29..7b7aaafac0dac18cf1ca9926c200255bec817e94 100644 (file)
@@ -256,6 +256,7 @@ struct intel_engine_cs {
 #define I915_DISPATCH_PINNED BIT(1)
 #define I915_DISPATCH_RS     BIT(2)
        int             (*emit_breadcrumb)(struct drm_i915_gem_request *req);
+       int             emit_breadcrumb_sz;
 
        /* Pass the request to the hardware queue (e.g. directly into
         * the legacy ringbuffer or to the end of an execlist).