Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk> --- drivers/gpu/drm/i915/i915_drv.h | 4 ++ drivers/gpu/drm/i915/i915_gem.c | 10 ++-- drivers/gpu/drm/i915/i915_gem_tiling.c | 87 ++++++++------------------------ 3 files changed, 29 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e2944e9..32cfe23 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1437,6 +1437,10 @@ int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset); int i915_gem_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle); + +uint32_t i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode); +uint32_t i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size, int tiling_mode); + /** * Returns true if seq1 is later than seq2. */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f660f20..987227b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1437,7 +1437,7 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj) obj->fault_mappable = false; } -static uint32_t +uint32_t i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) { uint32_t gtt_size; @@ -1465,7 +1465,7 @@ i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) * Return the required GTT alignment for an object, taking into account * potential fence register mapping. */ -static uint32_t +uint32_t i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size, int tiling_mode) @@ -2484,13 +2484,13 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) list_del(&obj->mm_list); list_move_tail(&obj->gtt_list, &dev_priv->mm.unbound_list); - /* Avoid an unnecessary call to unbind on rebind. */ - obj->map_and_fenceable = true; drm_mm_put_block(obj->gtt_space); obj->gtt_space = NULL; obj->gtt_offset = 0; + obj->map_and_fenceable = false; + return 0; } @@ -3689,8 +3689,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, obj->fence_reg = I915_FENCE_REG_NONE; obj->madv = I915_MADV_WILLNEED; - /* Avoid an unnecessary call to unbind on the first bind. */ - obj->map_and_fenceable = true; i915_gem_info_add_obj(obj->base.dev->dev_private, obj->base.size); } diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index cedbfd7..8e59bb5 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -252,47 +252,6 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) return true; } -/* Is the current GTT allocation valid for the change in tiling? */ -static bool -i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode) -{ - u32 size; - - if (tiling_mode == I915_TILING_NONE) - return true; - - if (INTEL_INFO(obj->base.dev)->gen >= 4) - return true; - - if (INTEL_INFO(obj->base.dev)->gen == 3) { - if (obj->gtt_offset & ~I915_FENCE_START_MASK) - return false; - } else { - if (obj->gtt_offset & ~I830_FENCE_START_MASK) - return false; - } - - /* - * Previous chips need to be aligned to the size of the smallest - * fence register that can contain the object. - */ - if (INTEL_INFO(obj->base.dev)->gen == 3) - size = 1024*1024; - else - size = 512*1024; - - while (size < obj->base.size) - size <<= 1; - - if (obj->gtt_space->size != size) - return false; - - if (obj->gtt_offset & (size - 1)) - return false; - - return true; -} - /** * Sets the tiling mode of an object, returning the required swizzling of * bit 6 of addresses in the object. @@ -365,33 +324,29 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, * has to also include the unfenced register the GPU uses * whilst executing a fenced command for an untiled object. */ - - obj->map_and_fenceable = - obj->gtt_space == NULL || - (obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end && - i915_gem_object_fence_ok(obj, args->tiling_mode)); - - /* Rebind if we need a change of alignment */ - if (!obj->map_and_fenceable) { - u32 unfenced_alignment = - i915_gem_get_unfenced_gtt_alignment(dev, - obj->base.size, - args->tiling_mode); - if (obj->gtt_offset & (unfenced_alignment - 1)) - ret = i915_gem_object_unbind(obj); + obj->fence_dirty = + obj->fenced_gpu_access || + obj->fence_reg != I915_FENCE_REG_NONE; + + obj->tiling_mode = args->tiling_mode; + obj->stride = args->stride; + + if (obj->gtt_space) { + unsigned fence_size = i915_gem_get_gtt_size(dev, obj->base.size, obj->tiling_mode); + unsigned fence_alignment = i915_gem_get_gtt_alignment(dev, + obj->base.size, + obj->tiling_mode); + bool fenceable = + obj->gtt_space->size == fence_size && + (obj->gtt_space->start & (fence_alignment - 1)) == 0; + bool mappable = + obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; + + obj->map_and_fenceable = mappable && fenceable; } - if (ret == 0) { - obj->fence_dirty = - obj->fenced_gpu_access || - obj->fence_reg != I915_FENCE_REG_NONE; - - obj->tiling_mode = args->tiling_mode; - obj->stride = args->stride; - - /* Force the fence to be reacquired for GTT access */ - i915_gem_release_mmap(obj); - } + /* Force the fence to be reacquired for GTT access */ + i915_gem_release_mmap(obj); } /* we have to maintain this existing ABI... */ args->stride = obj->stride; -- 1.7.10.4