From patchwork Fri Sep 2 03:55:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1121222 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p823tqpI019128 for ; Fri, 2 Sep 2011 03:56:13 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 12678A137C for ; Thu, 1 Sep 2011 20:55:51 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from cloud01.chad-versace.us (184-106-247-128.static.cloud-ips.com [184.106.247.128]) by gabe.freedesktop.org (Postfix) with ESMTP id D4590A132A for ; Thu, 1 Sep 2011 20:55:30 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by cloud01.chad-versace.us (Postfix) with ESMTP id 691E51D41C4; Fri, 2 Sep 2011 03:58:46 +0000 (UTC) X-Virus-Scanned: amavisd-new at static.cloud-ips.com X-Spam-Flag: NO X-Spam-Score: -1 X-Spam-Level: X-Spam-Status: No, score=-1 tagged_above=-100 required=3 tests=[ALL_TRUSTED=-1] autolearn=ham Received: from cloud01.chad-versace.us ([127.0.0.1]) by localhost (cloud01.static.cloud-ips.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ImRjvTwtXcrN; Fri, 2 Sep 2011 03:58:37 +0000 (UTC) Received: from localhost.localdomain (static-50-53-41-91.bvtn.or.frontiernet.net [50.53.41.91]) by cloud01.chad-versace.us (Postfix) with ESMTPSA id 9C6421D4094; Fri, 2 Sep 2011 03:58:33 +0000 (UTC) From: Ben Widawsky To: intel-gfx@lists.freedesktop.org Date: Thu, 1 Sep 2011 20:55:35 -0700 Message-Id: <1314935735-5451-1-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.7.6.1 Cc: Ben Widawsky Subject: [Intel-gfx] [PATCH] drm/i915: Dumb down the semaphore logic X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Fri, 02 Sep 2011 03:56:13 +0000 (UTC) While I think the previous code is correct, it was hard to follow and hard to debug. Since we already have a ring abstraction, might as well use it to handle the semaphore updates and compares. I don't expect this code to make semaphores better or worse, but you never know... Cc: Andrew Lutomirski Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 164 +++++++++++++++++++--------- drivers/gpu/drm/i915/intel_ringbuffer.h | 7 +- 3 files changed, 119 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 4934cf8..3693e83 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -784,7 +784,8 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, } from->sync_seqno[idx] = seqno; - return intel_ring_sync(to, from, seqno - 1); + + return to->sync_to(to, from, seqno - 1); } static int diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c30626e..c3d3906 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -313,81 +313,137 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) cleanup_pipe_control(ring); } +#define MBOX_UPDATE(ring, seqno) \ + intel_ring_emit(ring, \ + MI_SEMAPHORE_MBOX | \ + MI_SEMAPHORE_GLOBAL_GTT | /* Should be ignored */ \ + MI_SEMAPHORE_REGISTER | \ + MI_SEMAPHORE_UPDATE); \ + intel_ring_emit(ring, seqno) -static void -update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno) -{ - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int id; - - /* - * cs -> 1 = vcs, 0 = bcs - * vcs -> 1 = bcs, 0 = cs, - * bcs -> 1 = cs, 0 = vcs. - */ - id = ring - dev_priv->ring; - id += 2 - i; - id %= 3; - - intel_ring_emit(ring, - MI_SEMAPHORE_MBOX | - MI_SEMAPHORE_REGISTER | - MI_SEMAPHORE_UPDATE); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, - RING_SYNC_0(dev_priv->ring[id].mmio_base) + 4*i); -} - -static int -gen6_add_request(struct intel_ring_buffer *ring, - u32 *result) +static u32 +update_semaphore(struct intel_ring_buffer *ring, + u32 first, + u32 second) { u32 seqno; int ret; + seqno = i915_gem_get_seqno(ring->dev); ret = intel_ring_begin(ring, 10); if (ret) return ret; - seqno = i915_gem_get_seqno(ring->dev); - update_semaphore(ring, 0, seqno); - update_semaphore(ring, 1, seqno); - + MBOX_UPDATE(ring, seqno); + intel_ring_emit(ring, first); + MBOX_UPDATE(ring, seqno); + intel_ring_emit(ring, second); intel_ring_emit(ring, MI_STORE_DWORD_INDEX); intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); intel_ring_emit(ring, seqno); intel_ring_emit(ring, MI_USER_INTERRUPT); intel_ring_advance(ring); - *result = seqno; + return seqno; +} + +static int +gen6_blt_add_request(struct intel_ring_buffer *ring, + u32 *result) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + *result = update_semaphore(ring, + dev_priv->ring[RCS].mmio_base + 0x44, + dev_priv->ring[VCS].mmio_base + 0x40); return 0; } -int -intel_ring_sync(struct intel_ring_buffer *ring, - struct intel_ring_buffer *to, - u32 seqno) +static int +gen6_bsd_add_request(struct intel_ring_buffer *ring, + u32 *result) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + *result = update_semaphore(ring, + dev_priv->ring[RCS].mmio_base + 0x40, + dev_priv->ring[BCS].mmio_base + 0x44); + return 0; +} + +static int +gen6_render_add_request(struct intel_ring_buffer *ring, + u32 *result) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + *result = update_semaphore(ring, + dev_priv->ring[VCS].mmio_base + 0x44, + dev_priv->ring[BCS].mmio_base + 0x40); + return 0; +} + +static int +intel_ring_sync(struct intel_ring_buffer *comparer, + struct intel_ring_buffer *updater, + u32 seqno, + u32 semaphore_register) { int ret; + u32 temp = MI_SEMAPHORE_MBOX | + MI_SEMAPHORE_GLOBAL_GTT | /* Not needed */ + MI_SEMAPHORE_COMPARE; - ret = intel_ring_begin(ring, 4); + ret = intel_ring_begin(comparer, 4); if (ret) return ret; - intel_ring_emit(ring, - MI_SEMAPHORE_MBOX | - MI_SEMAPHORE_REGISTER | - intel_ring_sync_index(ring, to) << 17 | - MI_SEMAPHORE_COMPARE); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + temp |= MI_SEMAPHORE_REGISTER; + + intel_ring_emit(comparer, temp | semaphore_register); + intel_ring_emit(comparer, seqno); + intel_ring_emit(comparer, 0); + intel_ring_emit(comparer, MI_NOOP); + intel_ring_advance(comparer); return 0; } +/* VCS->RCS (RVSYNC) or BCS->RCS (RBSYNC) */ +int +render_ring_sync_to(struct intel_ring_buffer *comparer, + struct intel_ring_buffer *updater, + u32 seqno) +{ + WARN_ON(updater->semaphore_register[RCS] == 1); + return intel_ring_sync(comparer, updater, seqno, + updater->semaphore_register[RCS]); +} + +/* RCS->VCS (VRSYNC) or BCS->VCS (VBSYNC) */ +int +gen6_bsd_ring_sync_to(struct intel_ring_buffer *comparer, + struct intel_ring_buffer *updater, + u32 seqno) +{ + WARN_ON(updater->semaphore_register[VCS] == 1); + return intel_ring_sync(comparer, updater, seqno, + updater->semaphore_register[VCS]); +} + +/* RCS->BCS (BRSYNC) or VCS->BCS (BVSYNC) */ +int +gen6_blt_ring_sync_to(struct intel_ring_buffer *comparer, + struct intel_ring_buffer *updater, + u32 seqno) +{ + WARN_ON(updater->semaphore_register[BCS] == 1); + return intel_ring_sync(comparer, updater, seqno, + updater->semaphore_register[BCS]); +} + + + #define PIPE_CONTROL_FLUSH(ring__, addr__) \ do { \ intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ @@ -1027,6 +1083,8 @@ static const struct intel_ring_buffer render_ring = { .irq_put = render_ring_put_irq, .dispatch_execbuffer = render_ring_dispatch_execbuffer, .cleanup = render_ring_cleanup, + .sync_to = render_ring_sync_to, + .semaphore_register = {1, 2 << 16, 0 << 16}, /* invalid, RVSYNC, RBSYNC */ }; /* ring buffer for bit-stream decoder */ @@ -1149,11 +1207,13 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .init = init_ring_common, .write_tail = gen6_bsd_ring_write_tail, .flush = gen6_ring_flush, - .add_request = gen6_add_request, + .add_request = gen6_bsd_add_request, .get_seqno = ring_get_seqno, .irq_get = gen6_bsd_ring_get_irq, .irq_put = gen6_bsd_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, + .sync_to = gen6_bsd_ring_sync_to, + .semaphore_register = {0 << 16, 1, 2 << 16}, /* VRSYNC, 0, VBSYNC */ }; /* Blitter support (SandyBridge+) */ @@ -1279,12 +1339,14 @@ static const struct intel_ring_buffer gen6_blt_ring = { .init = blt_ring_init, .write_tail = ring_write_tail, .flush = blt_ring_flush, - .add_request = gen6_add_request, + .add_request = gen6_blt_add_request, .get_seqno = ring_get_seqno, .irq_get = blt_ring_get_irq, .irq_put = blt_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, .cleanup = blt_ring_cleanup, + .sync_to = gen6_blt_ring_sync_to, + .semaphore_register = {2 << 16, 0 << 16, 1}, /* BRSYNC, BVSYNC, 0 */ }; int intel_init_render_ring_buffer(struct drm_device *dev) @@ -1294,7 +1356,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->add_request = gen6_render_add_request; ring->irq_get = gen6_render_ring_get_irq; ring->irq_put = gen6_render_ring_put_irq; } else if (IS_GEN5(dev)) { @@ -1317,7 +1379,7 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) *ring = render_ring; if (INTEL_INFO(dev)->gen >= 6) { - ring->add_request = gen6_add_request; + ring->add_request = gen6_render_add_request; ring->irq_get = gen6_render_ring_get_irq; ring->irq_put = gen6_render_ring_put_irq; } else if (IS_GEN5(dev)) { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 39ac2b6..98052fd 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -75,7 +75,11 @@ struct intel_ring_buffer { int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, u32 offset, u32 length); void (*cleanup)(struct intel_ring_buffer *ring); + int (*sync_to)(struct intel_ring_buffer *ring, + struct intel_ring_buffer *to, + u32 seqno); + u32 semaphore_register[3]; /** * List of objects currently involved in rendering from the * ringbuffer. @@ -180,9 +184,6 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring, void intel_ring_advance(struct intel_ring_buffer *ring); u32 intel_ring_get_seqno(struct intel_ring_buffer *ring); -int intel_ring_sync(struct intel_ring_buffer *ring, - struct intel_ring_buffer *to, - u32 seqno); int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev);