On Fri, Jan 15, 2016 at 03:12:50PM +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursu...@intel.com>
> 
> At the moment execbuf ring selection is fully coupled to
> internal ring ids which is not a good thing on its own.
> 
> This dependency is also spread between two source files and
> not spelled out at either side which makes it hidden and
> fragile.
> 
> This patch decouples this dependency by introducing an explicit
> translation table of execbuf uAPI to ring id close to the only
> call site (i915_gem_do_execbuffer).
> 
> This way we are free to change driver internal implementation
> details without breaking userspace. All state relating to the
> uAPI is now contained in, or next to, i915_gem_do_execbuffer.
> 
> As a side benefit, this patch decreases the compiled size
> of i915_gem_do_execbuffer.
> 
> v2: Extract ring selection into eb_select_ring. (Chris Wilson)
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursu...@intel.com>
> Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
> Cc: Chris Wilson <ch...@chris-wilson.co.uk>

Yeah, this decoupling is nice, after all the point of include/uapi was to
make the uapi vs. internal headers clear.

Acked-by: Daniel Vetter <daniel.vet...@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/i915_drv.h            |   4 +-
>  drivers/gpu/drm/i915/i915_gem.c            |   2 +
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c | 139 
> +++++++++++++++--------------
>  drivers/gpu/drm/i915/intel_ringbuffer.h    |  10 +--
>  4 files changed, 81 insertions(+), 74 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index eb7bb97f7316..35d5d6099a44 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -334,7 +334,7 @@ struct drm_i915_file_private {
>               unsigned boosts;
>       } rps;
>  
> -     struct intel_engine_cs *bsd_ring;
> +     unsigned int bsd_ring;
>  };
>  
>  enum intel_dpll_id {
> @@ -1300,7 +1300,7 @@ struct i915_gem_mm {
>       bool busy;
>  
>       /* the indicator for dispatch video commands on two BSD rings */
> -     int bsd_ring_dispatch_index;
> +     unsigned int bsd_ring_dispatch_index;
>  
>       /** Bit 6 swizzling required for X tiling */
>       uint32_t bit_6_swizzle_x;
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index ddc21d4b388d..26e6842f2df3 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -5112,6 +5112,8 @@ int i915_gem_open(struct drm_device *dev, struct 
> drm_file *file)
>       spin_lock_init(&file_priv->mm.lock);
>       INIT_LIST_HEAD(&file_priv->mm.request_list);
>  
> +     file_priv->bsd_ring = -1;
> +
>       ret = i915_gem_context_open(dev, file);
>       if (ret)
>               kfree(file_priv);
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
> b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index d469c4779ff5..497a2f87836c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1328,33 +1328,23 @@ i915_gem_ringbuffer_submission(struct 
> i915_execbuffer_params *params,
>  
>  /**
>   * Find one BSD ring to dispatch the corresponding BSD command.
> - * The Ring ID is returned.
> + * The ring index is returned.
>   */
> -static int gen8_dispatch_bsd_ring(struct drm_device *dev,
> -                               struct drm_file *file)
> +static unsigned int
> +gen8_dispatch_bsd_ring(struct drm_i915_private *dev_priv, struct drm_file 
> *file)
>  {
> -     struct drm_i915_private *dev_priv = dev->dev_private;
>       struct drm_i915_file_private *file_priv = file->driver_priv;
>  
> -     /* Check whether the file_priv is using one ring */
> -     if (file_priv->bsd_ring)
> -             return file_priv->bsd_ring->id;
> -     else {
> -             /* If no, use the ping-pong mechanism to select one ring */
> -             int ring_id;
> -
> -             mutex_lock(&dev->struct_mutex);
> -             if (dev_priv->mm.bsd_ring_dispatch_index == 0) {
> -                     ring_id = VCS;
> -                     dev_priv->mm.bsd_ring_dispatch_index = 1;
> -             } else {
> -                     ring_id = VCS2;
> -                     dev_priv->mm.bsd_ring_dispatch_index = 0;
> -             }
> -             file_priv->bsd_ring = &dev_priv->ring[ring_id];
> -             mutex_unlock(&dev->struct_mutex);
> -             return ring_id;
> +     /* Check whether the file_priv has already selected one ring. */
> +     if ((int)file_priv->bsd_ring < 0) {
> +             /* If not, use the ping-pong mechanism to select one. */
> +             mutex_lock(&dev_priv->dev->struct_mutex);
> +             file_priv->bsd_ring = dev_priv->mm.bsd_ring_dispatch_index;
> +             dev_priv->mm.bsd_ring_dispatch_index ^= 1;
> +             mutex_unlock(&dev_priv->dev->struct_mutex);
>       }
> +
> +     return file_priv->bsd_ring;
>  }
>  
>  static struct drm_i915_gem_object *
> @@ -1377,6 +1367,63 @@ eb_get_batch(struct eb_vmas *eb)
>       return vma->obj;
>  }
>  
> +#define I915_USER_RINGS (4)
> +
> +static const enum intel_ring_id user_ring_map[I915_USER_RINGS + 1] = {
> +     [I915_EXEC_DEFAULT]     = RCS,
> +     [I915_EXEC_RENDER]      = RCS,
> +     [I915_EXEC_BLT]         = BCS,
> +     [I915_EXEC_BSD]         = VCS,
> +     [I915_EXEC_VEBOX]       = VECS
> +};
> +
> +static int
> +eb_select_ring(struct drm_i915_private *dev_priv,
> +            struct drm_file *file,
> +            struct drm_i915_gem_execbuffer2 *args,
> +            struct intel_engine_cs **ring)
> +{
> +     unsigned int user_ring_id = args->flags & I915_EXEC_RING_MASK;
> +
> +     if (user_ring_id > I915_USER_RINGS) {
> +             DRM_DEBUG("execbuf with unknown ring: %u\n", user_ring_id);
> +             return -EINVAL;
> +     }
> +
> +     if ((user_ring_id != I915_EXEC_BSD) &&
> +         ((args->flags & I915_EXEC_BSD_MASK) != 0)) {
> +             DRM_DEBUG("execbuf with non bsd ring but with invalid "
> +                       "bsd dispatch flags: %d\n", (int)(args->flags));
> +             return -EINVAL;
> +     }
> +
> +     if (user_ring_id == I915_EXEC_BSD && HAS_BSD2(dev_priv)) {
> +             unsigned int bsd_idx = args->flags & I915_EXEC_BSD_MASK;
> +
> +             if (bsd_idx == I915_EXEC_BSD_DEFAULT) {
> +                     bsd_idx = gen8_dispatch_bsd_ring(dev_priv, file);
> +             } else if (bsd_idx >= I915_EXEC_BSD_RING1 &&
> +                        bsd_idx <= I915_EXEC_BSD_RING2) {
> +                     bsd_idx--;
> +             } else {
> +                     DRM_DEBUG("execbuf with unknown bsd ring: %u\n",
> +                               bsd_idx);
> +                     return -EINVAL;
> +             }
> +
> +             *ring = &dev_priv->ring[_VCS(bsd_idx)];
> +     } else {
> +             *ring = &dev_priv->ring[user_ring_map[user_ring_id]];
> +     }
> +
> +     if (!intel_ring_initialized(*ring)) {
> +             DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id);
> +             return -EINVAL;
> +     }
> +
> +     return 0;
> +}
> +
>  static int
>  i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>                      struct drm_file *file,
> @@ -1414,51 +1461,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void 
> *data,
>       if (args->flags & I915_EXEC_IS_PINNED)
>               dispatch_flags |= I915_DISPATCH_PINNED;
>  
> -     if ((args->flags & I915_EXEC_RING_MASK) > LAST_USER_RING) {
> -             DRM_DEBUG("execbuf with unknown ring: %d\n",
> -                       (int)(args->flags & I915_EXEC_RING_MASK));
> -             return -EINVAL;
> -     }
> -
> -     if (((args->flags & I915_EXEC_RING_MASK) != I915_EXEC_BSD) &&
> -         ((args->flags & I915_EXEC_BSD_MASK) != 0)) {
> -             DRM_DEBUG("execbuf with non bsd ring but with invalid "
> -                     "bsd dispatch flags: %d\n", (int)(args->flags));
> -             return -EINVAL;
> -     } 
> -
> -     if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_DEFAULT)
> -             ring = &dev_priv->ring[RCS];
> -     else if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_BSD) {
> -             if (HAS_BSD2(dev)) {
> -                     int ring_id;
> -
> -                     switch (args->flags & I915_EXEC_BSD_MASK) {
> -                     case I915_EXEC_BSD_DEFAULT:
> -                             ring_id = gen8_dispatch_bsd_ring(dev, file);
> -                             ring = &dev_priv->ring[ring_id];
> -                             break;
> -                     case I915_EXEC_BSD_RING1:
> -                             ring = &dev_priv->ring[VCS];
> -                             break;
> -                     case I915_EXEC_BSD_RING2:
> -                             ring = &dev_priv->ring[VCS2];
> -                             break;
> -                     default:
> -                             DRM_DEBUG("execbuf with unknown bsd ring: %d\n",
> -                                       (int)(args->flags & 
> I915_EXEC_BSD_MASK));
> -                             return -EINVAL;
> -                     }
> -             } else
> -                     ring = &dev_priv->ring[VCS];
> -     } else
> -             ring = &dev_priv->ring[(args->flags & I915_EXEC_RING_MASK) - 1];
> -
> -     if (!intel_ring_initialized(ring)) {
> -             DRM_DEBUG("execbuf with invalid ring: %d\n",
> -                       (int)(args->flags & I915_EXEC_RING_MASK));
> -             return -EINVAL;
> -     }
> +     ret = eb_select_ring(dev_priv, file, args, &ring);
> +     if (ret)
> +             return ret;
>  
>       if (args->buffer_count < 1) {
>               DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h 
> b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 7349d9258191..fdc220fc2b18 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -148,14 +148,14 @@ struct  i915_ctx_workarounds {
>  struct  intel_engine_cs {
>       const char      *name;
>       enum intel_ring_id {
> -             RCS = 0x0,
> -             VCS,
> +             RCS = 0,
>               BCS,
> -             VECS,
> -             VCS2
> +             VCS,
> +             VCS2,   /* Keep instances of the same type engine together. */
> +             VECS
>       } id;
>  #define I915_NUM_RINGS 5
> -#define LAST_USER_RING (VECS + 1)
> +#define _VCS(n) (VCS + (n))
>       u32             mmio_base;
>       struct          drm_device *dev;
>       struct intel_ringbuffer *buffer;
> -- 
> 1.9.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to