drm/i915: Use the coarse ping-pong mechanism based on drm fd to dispatch the BSD...
authorZhao Yakui <yakui.zhao@intel.com>
Thu, 17 Apr 2014 02:37:40 +0000 (10:37 +0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 5 May 2014 07:08:49 +0000 (09:08 +0200)
The BDW GT3 has two independent BSD rings, which can be used to process the
video commands. To be simpler, it is transparent to user-space driver/middle.
Instead the kernel driver will decide which ring is to dispatch the BSD video
command.

As every BSD ring is powerful, it is enough to dispatch the BSD video command
based on the drm fd. In such case it can play back video stream while encoding
another video stream. The coarse ping-pong mechanism is used to determine
which BSD ring is used to dispatch the BSD video command.

V1->V2: Follow Daniel's comment and use the simple ping-pong mechanism.
This is only to add the support of dual BSD rings on BDW GT3 machine.
The further optimization will be considered in another patch set.

V2->V3: Follow Daniel's comment to use the struct_mutext instead of
atomic_t during determining which ring can be used to dispatch Video command.

Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_execbuffer.c

index 58f2c467d68ef1eef48bdd0d5b53b5b7bbb0f4db..66e4ba1a16c17a74737361e3aeafff2fa16242af 100644 (file)
@@ -1573,6 +1573,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        spin_lock_init(&dev_priv->backlight_lock);
        spin_lock_init(&dev_priv->uncore.lock);
        spin_lock_init(&dev_priv->mm.object_stat_lock);
+       dev_priv->ring_index = 0;
        mutex_init(&dev_priv->dpio_lock);
        mutex_init(&dev_priv->modeset_restore_lock);
 
@@ -1930,6 +1931,8 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
 {
        struct drm_i915_file_private *file_priv = file->driver_priv;
 
+       if (file_priv && file_priv->bsd_ring)
+               file_priv->bsd_ring = NULL;
        kfree(file_priv);
 }
 
index 5411079b269776a2a9ed509aee53749b8223475f..272aa7a6fbdb87f7de20e2e7df1d676f49699756 100644 (file)
@@ -1473,6 +1473,8 @@ struct drm_i915_private {
        struct i915_dri1_state dri1;
        /* Old ums support infrastructure, same warning applies. */
        struct i915_ums_state ums;
+       /* the indicator for dispatch video commands on two BSD rings */
+       int ring_index;
 };
 
 static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
@@ -1680,6 +1682,7 @@ struct drm_i915_file_private {
 
        struct i915_hw_context *private_default_ctx;
        atomic_t rps_wait_boost;
+       struct  intel_ring_buffer *bsd_ring;
 };
 
 /*
index 0aa1b4cb1f6dbff4a67fe4b45d1e5b0597e8a6f3..2f2047d4863d03a2285d828af7d3f0ad638f63ae 100644 (file)
@@ -1001,6 +1001,37 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev,
        return 0;
 }
 
+/**
+ * Find one BSD ring to dispatch the corresponding BSD command.
+ * The Ring ID is returned.
+ */
+static int gen8_dispatch_bsd_ring(struct drm_device *dev,
+                                 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->ring_index == 0) {
+                       ring_id = VCS;
+                       dev_priv->ring_index = 1;
+               } else {
+                       ring_id = VCS2;
+                       dev_priv->ring_index = 0;
+               }
+               file_priv->bsd_ring = &dev_priv->ring[ring_id];
+               mutex_unlock(&dev->struct_mutex);
+               return ring_id;
+       }
+}
+
 static int
 i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                       struct drm_file *file,
@@ -1045,7 +1076,14 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 
        if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_DEFAULT)
                ring = &dev_priv->ring[RCS];
-       else
+       else if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_BSD) {
+               if (HAS_BSD2(dev)) {
+                       int ring_id;
+                       ring_id = gen8_dispatch_bsd_ring(dev, file);
+                       ring = &dev_priv->ring[ring_id];
+               } else
+                       ring = &dev_priv->ring[VCS];
+       } else
                ring = &dev_priv->ring[(args->flags & I915_EXEC_RING_MASK) - 1];
 
        if (!intel_ring_initialized(ring)) {
This page took 0.033754 seconds and 5 git commands to generate.