Align unfenced buffers on older hardware to the power-of-two object size.
The docs suggest that it should be possible to align only to a power-of-two
tile height, but using the already computed fence size is easier. We
also have to make sure that we unbind misaligned buffers upon tiling
changes.

Reported-and-tested-by: Sitosfe Wheeler <[email protected]>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=36326
Signed-off-by: Chris Wilson <[email protected]>
Cc: [email protected]
---
 drivers/gpu/drm/i915/i915_dma.c        |    2 +-
 drivers/gpu/drm/i915/i915_drv.h        |    3 ++-
 drivers/gpu/drm/i915/i915_gem.c        |   30 ++++++++++++++----------------
 drivers/gpu/drm/i915/i915_gem_tiling.c |    3 ++-
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 403e69f..1a5bd0f 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -771,7 +771,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
                value = HAS_BLT(dev);
                break;
        case I915_PARAM_HAS_RELAXED_FENCING:
-               value = 1;
+               value = 2;
                break;
        case I915_PARAM_HAS_COHERENT_RINGS:
                value = 1;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b492779..a030e38 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1188,7 +1188,8 @@ void i915_gem_free_all_phys_object(struct drm_device 
*dev);
 void i915_gem_release(struct drm_device *dev, struct drm_file *file);
 
 uint32_t
-i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj);
+i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj,
+                                   int tiling_mode);
 
 /* i915_gem_gtt.c */
 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 7ce3f35..896aac7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1430,35 +1430,32 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object 
*obj)
  * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an
  *                                      unfenced object
  * @obj: object to check
+ * @tiling_mode: tiling mode of the object
  *
  * Return the required GTT alignment for an object, only taking into account
  * unfenced tiled surface requirements.
  */
 uint32_t
-i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj)
+i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj,
+                                   int tiling_mode)
 {
        struct drm_device *dev = obj->base.dev;
-       int tile_height;
+
+       if (tiling_mode == I915_TILING_NONE)
+               return 4096;
 
        /*
         * Minimum alignment is 4k (GTT page size) for sane hw.
         */
-       if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) ||
-           obj->tiling_mode == I915_TILING_NONE)
+       dev = obj->base.dev;
+       if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev))
                return 4096;
 
-       /*
-        * Older chips need unfenced tiled buffers to be aligned to the left
-        * edge of an even tile row (where tile rows are counted as if the bo is
-        * placed in a fenced gtt region).
+       /* Previous hardware however needs to be aligned to a power-of-two
+        * tile height. The simplest method for determining this is to reuse
+        * the power-of-tile object size.
         */
-       if (IS_GEN2(dev) ||
-           (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
-               tile_height = 32;
-       else
-               tile_height = 8;
-
-       return tile_height * obj->stride * 2;
+       return i915_gem_get_gtt_size(obj);
 }
 
 int
@@ -2752,7 +2749,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object 
*obj,
 
        fence_size = i915_gem_get_gtt_size(obj);
        fence_alignment = i915_gem_get_gtt_alignment(obj);
-       unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj);
+       unfenced_alignment =
+               i915_gem_get_unfenced_gtt_alignment(obj, obj->tiling_mode);
 
        if (alignment == 0)
                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 281ad3d..c775f03 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -348,7 +348,8 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
                /* Rebind if we need a change of alignment */
                if (!obj->map_and_fenceable) {
                        u32 unfenced_alignment =
-                               i915_gem_get_unfenced_gtt_alignment(obj);
+                               i915_gem_get_unfenced_gtt_alignment(obj,
+                                                                   
args->tiling_mode);
                        if (obj->gtt_offset & (unfenced_alignment - 1))
                                ret = i915_gem_object_unbind(obj);
                }
-- 
1.7.5.3

_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to