|
@@ -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)) {
|