From patchwork Mon Sep 5 03:52:42 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1124522 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p853tTKA029898 for ; Mon, 5 Sep 2011 03:55:51 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6CE7AA08AA for ; Sun, 4 Sep 2011 20:55:29 -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 8BF22A1B7D for ; Sun, 4 Sep 2011 20:52:33 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by cloud01.chad-versace.us (Postfix) with ESMTP id E70571D41C2; Mon, 5 Sep 2011 03:55:51 +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 W7B9sjtSFYPM; Mon, 5 Sep 2011 03:55:43 +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 D358C1D4094; Mon, 5 Sep 2011 03:55:42 +0000 (UTC) From: Ben Widawsky To: intel-gfx@lists.freedesktop.org Date: Sun, 4 Sep 2011 20:52:42 -0700 Message-Id: <1315194762-6129-1-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.7.6.1 Cc: Daniel Vetter , 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 (demeter1.kernel.org [140.211.167.41]); Mon, 05 Sep 2011 03:55:52 +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: Chris Wilson Cc: Daniel Vetter Cc: Eric Anholt Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +- drivers/gpu/drm/i915/i915_reg.h | 7 + drivers/gpu/drm/i915/intel_ringbuffer.c | 171 ++++++++++++++++++++------- drivers/gpu/drm/i915/intel_ringbuffer.h | 7 +- 4 files changed, 139 insertions(+), 49 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/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 542453f..f0b5287 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -194,6 +194,13 @@ #define MI_SEMAPHORE_UPDATE (1<<21) #define MI_SEMAPHORE_COMPARE (1<<20) #define MI_SEMAPHORE_REGISTER (1<<18) +#define MI_SEMAPHORE_SYNC_RV (2<<16) +#define MI_SEMAPHORE_SYNC_RB (0<<16) +#define MI_SEMAPHORE_SYNC_VR (0<<16) +#define MI_SEMAPHORE_SYNC_VB (2<<16) +#define MI_SEMAPHORE_SYNC_BR (2<<16) +#define MI_SEMAPHORE_SYNC_BV (0<<16) +#define MI_SEMAPHORE_SYNC_INVALID (1<<0) /* * 3D instructions used by the kernel */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c30626e..ecb33bd 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -315,79 +315,148 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) } static void -update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno) +update_mboxes(struct intel_ring_buffer *ring, + u32 seqno, + u32 mmio_offset) { - 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, MI_SEMAPHORE_MBOX | + MI_SEMAPHORE_GLOBAL_GTT | /* Should be ignored */ + 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); + intel_ring_emit(ring, mmio_offset); } -static int +/** + * gen6_add_request - Update the semaphore mailbox registers + * + * @ring - ring that is adding a request + * @mbox1_reg - mailbox address for RCS or VCS ring + * @mbox2_reg - mailbox address for VCS or BCS ring + * + * Update the mailbox registers in the *other* rings with the current seqno. + */ +static u32 gen6_add_request(struct intel_ring_buffer *ring, - u32 *result) + u32 mbox1_reg, + u32 mbox2_reg) { 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); - + update_mboxes(ring, seqno, mbox1_reg); + update_mboxes(ring, seqno, mbox2_reg); 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 = gen6_add_request(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 = gen6_add_request(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 = gen6_add_request(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 +1096,10 @@ 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 = {MI_SEMAPHORE_SYNC_INVALID, + MI_SEMAPHORE_SYNC_RV, + MI_SEMAPHORE_SYNC_RB}, }; /* ring buffer for bit-stream decoder */ @@ -1149,11 +1222,15 @@ 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 = {MI_SEMAPHORE_SYNC_VR, + MI_SEMAPHORE_SYNC_INVALID, + MI_SEMAPHORE_SYNC_VB}, }; /* Blitter support (SandyBridge+) */ @@ -1279,12 +1356,16 @@ 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 = {MI_SEMAPHORE_SYNC_BR, + MI_SEMAPHORE_SYNC_BV, + MI_SEMAPHORE_SYNC_INVALID}, }; int intel_init_render_ring_buffer(struct drm_device *dev) @@ -1294,7 +1375,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 +1398,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);