aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>2016-01-15 10:12:50 -0500
committerTvrtko Ursulin <tvrtko.ursulin@intel.com>2016-01-21 05:55:44 -0500
commitde1add360522c876c25ef2bbbbab1c94bdb509ab (patch)
tree03f880cd80a81a438eea1002fa58bae2e0cc2e1c /drivers
parent7c17d377374ddbcfb7873366559fc4ed8b296e11 (diff)
drm/i915: Decouple execbuf uAPI from internal implementation
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@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1452870770-13981-1-git-send-email-tvrtko.ursulin@linux.intel.com
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h4
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c139
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h10
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 840368de3f4f..204661f9873d 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 {
334 unsigned boosts; 334 unsigned boosts;
335 } rps; 335 } rps;
336 336
337 struct intel_engine_cs *bsd_ring; 337 unsigned int bsd_ring;
338}; 338};
339 339
340enum intel_dpll_id { 340enum intel_dpll_id {
@@ -1299,7 +1299,7 @@ struct i915_gem_mm {
1299 bool busy; 1299 bool busy;
1300 1300
1301 /* the indicator for dispatch video commands on two BSD rings */ 1301 /* the indicator for dispatch video commands on two BSD rings */
1302 int bsd_ring_dispatch_index; 1302 unsigned int bsd_ring_dispatch_index;
1303 1303
1304 /** Bit 6 swizzling required for X tiling */ 1304 /** Bit 6 swizzling required for X tiling */
1305 uint32_t bit_6_swizzle_x; 1305 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 6a3e4ee7f7e2..0ed731ed6976 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5141,6 +5141,8 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file)
5141 spin_lock_init(&file_priv->mm.lock); 5141 spin_lock_init(&file_priv->mm.lock);
5142 INIT_LIST_HEAD(&file_priv->mm.request_list); 5142 INIT_LIST_HEAD(&file_priv->mm.request_list);
5143 5143
5144 file_priv->bsd_ring = -1;
5145
5144 ret = i915_gem_context_open(dev, file); 5146 ret = i915_gem_context_open(dev, file);
5145 if (ret) 5147 if (ret)
5146 kfree(file_priv); 5148 kfree(file_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index dc32018ee2e9..2dc08ce1079a 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1325,33 +1325,23 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params,
1325 1325
1326/** 1326/**
1327 * Find one BSD ring to dispatch the corresponding BSD command. 1327 * Find one BSD ring to dispatch the corresponding BSD command.
1328 * The Ring ID is returned. 1328 * The ring index is returned.
1329 */ 1329 */
1330static int gen8_dispatch_bsd_ring(struct drm_device *dev, 1330static unsigned int
1331 struct drm_file *file) 1331gen8_dispatch_bsd_ring(struct drm_i915_private *dev_priv, struct drm_file *file)
1332{ 1332{
1333 struct drm_i915_private *dev_priv = dev->dev_private;
1334 struct drm_i915_file_private *file_priv = file->driver_priv; 1333 struct drm_i915_file_private *file_priv = file->driver_priv;
1335 1334
1336 /* Check whether the file_priv is using one ring */ 1335 /* Check whether the file_priv has already selected one ring. */
1337 if (file_priv->bsd_ring) 1336 if ((int)file_priv->bsd_ring < 0) {
1338 return file_priv->bsd_ring->id; 1337 /* If not, use the ping-pong mechanism to select one. */
1339 else { 1338 mutex_lock(&dev_priv->dev->struct_mutex);
1340 /* If no, use the ping-pong mechanism to select one ring */ 1339 file_priv->bsd_ring = dev_priv->mm.bsd_ring_dispatch_index;
1341 int ring_id; 1340 dev_priv->mm.bsd_ring_dispatch_index ^= 1;
1342 1341 mutex_unlock(&dev_priv->dev->struct_mutex);
1343 mutex_lock(&dev->struct_mutex);
1344 if (dev_priv->mm.bsd_ring_dispatch_index == 0) {
1345 ring_id = VCS;
1346 dev_priv->mm.bsd_ring_dispatch_index = 1;
1347 } else {
1348 ring_id = VCS2;
1349 dev_priv->mm.bsd_ring_dispatch_index = 0;
1350 }
1351 file_priv->bsd_ring = &dev_priv->ring[ring_id];
1352 mutex_unlock(&dev->struct_mutex);
1353 return ring_id;
1354 } 1342 }
1343
1344 return file_priv->bsd_ring;
1355} 1345}
1356 1346
1357static struct drm_i915_gem_object * 1347static struct drm_i915_gem_object *
@@ -1374,6 +1364,63 @@ eb_get_batch(struct eb_vmas *eb)
1374 return vma->obj; 1364 return vma->obj;
1375} 1365}
1376 1366
1367#define I915_USER_RINGS (4)
1368
1369static const enum intel_ring_id user_ring_map[I915_USER_RINGS + 1] = {
1370 [I915_EXEC_DEFAULT] = RCS,
1371 [I915_EXEC_RENDER] = RCS,
1372 [I915_EXEC_BLT] = BCS,
1373 [I915_EXEC_BSD] = VCS,
1374 [I915_EXEC_VEBOX] = VECS
1375};
1376
1377static int
1378eb_select_ring(struct drm_i915_private *dev_priv,
1379 struct drm_file *file,
1380 struct drm_i915_gem_execbuffer2 *args,
1381 struct intel_engine_cs **ring)
1382{
1383 unsigned int user_ring_id = args->flags & I915_EXEC_RING_MASK;
1384
1385 if (user_ring_id > I915_USER_RINGS) {
1386 DRM_DEBUG("execbuf with unknown ring: %u\n", user_ring_id);
1387 return -EINVAL;
1388 }
1389
1390 if ((user_ring_id != I915_EXEC_BSD) &&
1391 ((args->flags & I915_EXEC_BSD_MASK) != 0)) {
1392 DRM_DEBUG("execbuf with non bsd ring but with invalid "
1393 "bsd dispatch flags: %d\n", (int)(args->flags));
1394 return -EINVAL;
1395 }
1396
1397 if (user_ring_id == I915_EXEC_BSD && HAS_BSD2(dev_priv)) {
1398 unsigned int bsd_idx = args->flags & I915_EXEC_BSD_MASK;
1399
1400 if (bsd_idx == I915_EXEC_BSD_DEFAULT) {
1401 bsd_idx = gen8_dispatch_bsd_ring(dev_priv, file);
1402 } else if (bsd_idx >= I915_EXEC_BSD_RING1 &&
1403 bsd_idx <= I915_EXEC_BSD_RING2) {
1404 bsd_idx--;
1405 } else {
1406 DRM_DEBUG("execbuf with unknown bsd ring: %u\n",
1407 bsd_idx);
1408 return -EINVAL;
1409 }
1410
1411 *ring = &dev_priv->ring[_VCS(bsd_idx)];
1412 } else {
1413 *ring = &dev_priv->ring[user_ring_map[user_ring_id]];
1414 }
1415
1416 if (!intel_ring_initialized(*ring)) {
1417 DRM_DEBUG("execbuf with invalid ring: %u\n", user_ring_id);
1418 return -EINVAL;
1419 }
1420
1421 return 0;
1422}
1423
1377static int 1424static int
1378i915_gem_do_execbuffer(struct drm_device *dev, void *data, 1425i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1379 struct drm_file *file, 1426 struct drm_file *file,
@@ -1412,51 +1459,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
1412 if (args->flags & I915_EXEC_IS_PINNED) 1459 if (args->flags & I915_EXEC_IS_PINNED)
1413 dispatch_flags |= I915_DISPATCH_PINNED; 1460 dispatch_flags |= I915_DISPATCH_PINNED;
1414 1461
1415 if ((args->flags & I915_EXEC_RING_MASK) > LAST_USER_RING) { 1462 ret = eb_select_ring(dev_priv, file, args, &ring);
1416 DRM_DEBUG("execbuf with unknown ring: %d\n", 1463 if (ret)
1417 (int)(args->flags & I915_EXEC_RING_MASK)); 1464 return ret;
1418 return -EINVAL;
1419 }
1420
1421 if (((args->flags & I915_EXEC_RING_MASK) != I915_EXEC_BSD) &&
1422 ((args->flags & I915_EXEC_BSD_MASK) != 0)) {
1423 DRM_DEBUG("execbuf with non bsd ring but with invalid "
1424 "bsd dispatch flags: %d\n", (int)(args->flags));
1425 return -EINVAL;
1426 }
1427
1428 if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_DEFAULT)
1429 ring = &dev_priv->ring[RCS];
1430 else if ((args->flags & I915_EXEC_RING_MASK) == I915_EXEC_BSD) {
1431 if (HAS_BSD2(dev)) {
1432 int ring_id;
1433
1434 switch (args->flags & I915_EXEC_BSD_MASK) {
1435 case I915_EXEC_BSD_DEFAULT:
1436 ring_id = gen8_dispatch_bsd_ring(dev, file);
1437 ring = &dev_priv->ring[ring_id];
1438 break;
1439 case I915_EXEC_BSD_RING1:
1440 ring = &dev_priv->ring[VCS];
1441 break;
1442 case I915_EXEC_BSD_RING2:
1443 ring = &dev_priv->ring[VCS2];
1444 break;
1445 default:
1446 DRM_DEBUG("execbuf with unknown bsd ring: %d\n",
1447 (int)(args->flags & I915_EXEC_BSD_MASK));
1448 return -EINVAL;
1449 }
1450 } else
1451 ring = &dev_priv->ring[VCS];
1452 } else
1453 ring = &dev_priv->ring[(args->flags & I915_EXEC_RING_MASK) - 1];
1454
1455 if (!intel_ring_initialized(ring)) {
1456 DRM_DEBUG("execbuf with invalid ring: %d\n",
1457 (int)(args->flags & I915_EXEC_RING_MASK));
1458 return -EINVAL;
1459 }
1460 1465
1461 if (args->buffer_count < 1) { 1466 if (args->buffer_count < 1) {
1462 DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); 1467 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 b6c7cd2b8a40..5b44ca63405d 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -149,14 +149,14 @@ struct i915_ctx_workarounds {
149struct intel_engine_cs { 149struct intel_engine_cs {
150 const char *name; 150 const char *name;
151 enum intel_ring_id { 151 enum intel_ring_id {
152 RCS = 0x0, 152 RCS = 0,
153 VCS,
154 BCS, 153 BCS,
155 VECS, 154 VCS,
156 VCS2 155 VCS2, /* Keep instances of the same type engine together. */
156 VECS
157 } id; 157 } id;
158#define I915_NUM_RINGS 5 158#define I915_NUM_RINGS 5
159#define LAST_USER_RING (VECS + 1) 159#define _VCS(n) (VCS + (n))
160 u32 mmio_base; 160 u32 mmio_base;
161 struct drm_device *dev; 161 struct drm_device *dev;
162 struct intel_ringbuffer *buffer; 162 struct intel_ringbuffer *buffer;