[Intel-gfx] [PATCH v2] drm/i915: Decouple execbuf uAPI from internal implementation
Daniel Vetter
daniel at ffwll.ch
Thu Jan 21 02:22:28 PST 2016
On Fri, Jan 15, 2016 at 03:12:50PM +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin at 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.ursulin at intel.com>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: Chris Wilson <chris at 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.vetter at 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
More information about the Intel-gfx
mailing list