diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 71 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_tiling.c | 4 |
3 files changed, 41 insertions, 38 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6042921fdf3f..ce7914c4c044 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1195,7 +1195,9 @@ void i915_gem_free_all_phys_object(struct drm_device *dev); | |||
1195 | void i915_gem_release(struct drm_device *dev, struct drm_file *file); | 1195 | void i915_gem_release(struct drm_device *dev, struct drm_file *file); |
1196 | 1196 | ||
1197 | uint32_t | 1197 | uint32_t |
1198 | i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj); | 1198 | i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, |
1199 | uint32_t size, | ||
1200 | int tiling_mode); | ||
1199 | 1201 | ||
1200 | /* i915_gem_gtt.c */ | 1202 | /* i915_gem_gtt.c */ |
1201 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); | 1203 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5c0d1247f453..a087e1bf0c2f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1374,25 +1374,24 @@ i915_gem_free_mmap_offset(struct drm_i915_gem_object *obj) | |||
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | static uint32_t | 1376 | static uint32_t |
1377 | i915_gem_get_gtt_size(struct drm_i915_gem_object *obj) | 1377 | i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) |
1378 | { | 1378 | { |
1379 | struct drm_device *dev = obj->base.dev; | 1379 | uint32_t gtt_size; |
1380 | uint32_t size; | ||
1381 | 1380 | ||
1382 | if (INTEL_INFO(dev)->gen >= 4 || | 1381 | if (INTEL_INFO(dev)->gen >= 4 || |
1383 | obj->tiling_mode == I915_TILING_NONE) | 1382 | tiling_mode == I915_TILING_NONE) |
1384 | return obj->base.size; | 1383 | return size; |
1385 | 1384 | ||
1386 | /* Previous chips need a power-of-two fence region when tiling */ | 1385 | /* Previous chips need a power-of-two fence region when tiling */ |
1387 | if (INTEL_INFO(dev)->gen == 3) | 1386 | if (INTEL_INFO(dev)->gen == 3) |
1388 | size = 1024*1024; | 1387 | gtt_size = 1024*1024; |
1389 | else | 1388 | else |
1390 | size = 512*1024; | 1389 | gtt_size = 512*1024; |
1391 | 1390 | ||
1392 | while (size < obj->base.size) | 1391 | while (gtt_size < size) |
1393 | size <<= 1; | 1392 | gtt_size <<= 1; |
1394 | 1393 | ||
1395 | return size; | 1394 | return gtt_size; |
1396 | } | 1395 | } |
1397 | 1396 | ||
1398 | /** | 1397 | /** |
@@ -1403,59 +1402,52 @@ i915_gem_get_gtt_size(struct drm_i915_gem_object *obj) | |||
1403 | * potential fence register mapping. | 1402 | * potential fence register mapping. |
1404 | */ | 1403 | */ |
1405 | static uint32_t | 1404 | static uint32_t |
1406 | i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj) | 1405 | i915_gem_get_gtt_alignment(struct drm_device *dev, |
1406 | uint32_t size, | ||
1407 | int tiling_mode) | ||
1407 | { | 1408 | { |
1408 | struct drm_device *dev = obj->base.dev; | ||
1409 | |||
1410 | /* | 1409 | /* |
1411 | * Minimum alignment is 4k (GTT page size), but might be greater | 1410 | * Minimum alignment is 4k (GTT page size), but might be greater |
1412 | * if a fence register is needed for the object. | 1411 | * if a fence register is needed for the object. |
1413 | */ | 1412 | */ |
1414 | if (INTEL_INFO(dev)->gen >= 4 || | 1413 | if (INTEL_INFO(dev)->gen >= 4 || |
1415 | obj->tiling_mode == I915_TILING_NONE) | 1414 | tiling_mode == I915_TILING_NONE) |
1416 | return 4096; | 1415 | return 4096; |
1417 | 1416 | ||
1418 | /* | 1417 | /* |
1419 | * Previous chips need to be aligned to the size of the smallest | 1418 | * Previous chips need to be aligned to the size of the smallest |
1420 | * fence register that can contain the object. | 1419 | * fence register that can contain the object. |
1421 | */ | 1420 | */ |
1422 | return i915_gem_get_gtt_size(obj); | 1421 | return i915_gem_get_gtt_size(dev, size, tiling_mode); |
1423 | } | 1422 | } |
1424 | 1423 | ||
1425 | /** | 1424 | /** |
1426 | * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an | 1425 | * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an |
1427 | * unfenced object | 1426 | * unfenced object |
1428 | * @obj: object to check | 1427 | * @dev: the device |
1428 | * @size: size of the object | ||
1429 | * @tiling_mode: tiling mode of the object | ||
1429 | * | 1430 | * |
1430 | * Return the required GTT alignment for an object, only taking into account | 1431 | * Return the required GTT alignment for an object, only taking into account |
1431 | * unfenced tiled surface requirements. | 1432 | * unfenced tiled surface requirements. |
1432 | */ | 1433 | */ |
1433 | uint32_t | 1434 | uint32_t |
1434 | i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) | 1435 | i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, |
1436 | uint32_t size, | ||
1437 | int tiling_mode) | ||
1435 | { | 1438 | { |
1436 | struct drm_device *dev = obj->base.dev; | ||
1437 | int tile_height; | ||
1438 | |||
1439 | /* | 1439 | /* |
1440 | * Minimum alignment is 4k (GTT page size) for sane hw. | 1440 | * Minimum alignment is 4k (GTT page size) for sane hw. |
1441 | */ | 1441 | */ |
1442 | if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || | 1442 | if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || |
1443 | obj->tiling_mode == I915_TILING_NONE) | 1443 | tiling_mode == I915_TILING_NONE) |
1444 | return 4096; | 1444 | return 4096; |
1445 | 1445 | ||
1446 | /* | 1446 | /* Previous hardware however needs to be aligned to a power-of-two |
1447 | * Older chips need unfenced tiled buffers to be aligned to the left | 1447 | * tile height. The simplest method for determining this is to reuse |
1448 | * edge of an even tile row (where tile rows are counted as if the bo is | 1448 | * the power-of-tile object size. |
1449 | * placed in a fenced gtt region). | ||
1450 | */ | 1449 | */ |
1451 | if (IS_GEN2(dev)) | 1450 | return i915_gem_get_gtt_size(dev, size, tiling_mode); |
1452 | tile_height = 16; | ||
1453 | else if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) | ||
1454 | tile_height = 32; | ||
1455 | else | ||
1456 | tile_height = 8; | ||
1457 | |||
1458 | return tile_height * obj->stride * 2; | ||
1459 | } | 1451 | } |
1460 | 1452 | ||
1461 | int | 1453 | int |
@@ -2744,9 +2736,16 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2744 | return -EINVAL; | 2736 | return -EINVAL; |
2745 | } | 2737 | } |
2746 | 2738 | ||
2747 | fence_size = i915_gem_get_gtt_size(obj); | 2739 | fence_size = i915_gem_get_gtt_size(dev, |
2748 | fence_alignment = i915_gem_get_gtt_alignment(obj); | 2740 | obj->base.size, |
2749 | unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj); | 2741 | obj->tiling_mode); |
2742 | fence_alignment = i915_gem_get_gtt_alignment(dev, | ||
2743 | obj->base.size, | ||
2744 | obj->tiling_mode); | ||
2745 | unfenced_alignment = | ||
2746 | i915_gem_get_unfenced_gtt_alignment(dev, | ||
2747 | obj->base.size, | ||
2748 | obj->tiling_mode); | ||
2750 | 2749 | ||
2751 | if (alignment == 0) | 2750 | if (alignment == 0) |
2752 | alignment = map_and_fenceable ? fence_alignment : | 2751 | alignment = map_and_fenceable ? fence_alignment : |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 82d70fd9e933..99c4faa59d8f 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -348,7 +348,9 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
348 | /* Rebind if we need a change of alignment */ | 348 | /* Rebind if we need a change of alignment */ |
349 | if (!obj->map_and_fenceable) { | 349 | if (!obj->map_and_fenceable) { |
350 | u32 unfenced_alignment = | 350 | u32 unfenced_alignment = |
351 | i915_gem_get_unfenced_gtt_alignment(obj); | 351 | i915_gem_get_unfenced_gtt_alignment(dev, |
352 | obj->base.size, | ||
353 | args->tiling_mode); | ||
352 | if (obj->gtt_offset & (unfenced_alignment - 1)) | 354 | if (obj->gtt_offset & (unfenced_alignment - 1)) |
353 | ret = i915_gem_object_unbind(obj); | 355 | ret = i915_gem_object_unbind(obj); |
354 | } | 356 | } |