This avoids stalling on the gpu. With the preparation from the previous patch, this is really just a small change.
Thanks to Owain Ainsworth <zer...@googlemail.com> for coming up with the idea for this patch and hashing out the implementation with me on irc. Signed-off-by: Daniel Vetter <daniel.vet...@ffwll.ch> --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ drivers/gpu/drm/i915/i915_gem.c | 9 +++++++++ drivers/gpu/drm/i915/i915_gem_tiling.c | 26 ++++++-------------------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7aec3ec..174269c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -698,6 +698,12 @@ struct drm_i915_gem_object { */ int fence_reg; + /** + * Tiling changes can happen asynchronous to avoid gpu stalls. + * This will be set if the current fencing may be invalid. + */ + int fence_invalid; + /** How many users have pinned this object in GTT space */ int pin_count; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8e73a12..8e18c9d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2485,6 +2485,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) struct drm_i915_fence_reg *reg = NULL; int ret; + BUG_ON(obj_priv->fence_invalid); + /* Just update our place in the LRU if our fence is getting used. */ if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); @@ -2554,6 +2556,13 @@ i915_gem_object_adjust_fencing(struct drm_gem_object *obj) struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; + if (obj_priv->fence_invalid) { + ret = i915_gem_object_put_fence_reg(obj); + if (ret != 0) + return ret; + } + obj_priv->fence_invalid = 0; + if (!i915_gem_object_fence_offset_ok(obj, obj_priv->tiling_mode)) { ret = i915_gem_object_unbind(obj); if (ret != 0) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 00f264d..aadaaa6 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -322,30 +322,16 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); if (args->tiling_mode != obj_priv->tiling_mode || args->stride != obj_priv->stride) { - /* We need to rebind the object if its current allocation - * no longer meets the alignment restrictions for its new - * tiling mode. Otherwise we can just leave it alone, but - * need to ensure that any fence register is cleared. - */ - if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) - ret = i915_gem_object_unbind(obj); - else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) - ret = i915_gem_object_put_fence_reg(obj); - else - i915_gem_release_mmap(obj); - - if (ret != 0) { - WARN(ret != -ERESTARTSYS, - "failed to reset object for tiling switch"); - args->tiling_mode = obj_priv->tiling_mode; - args->stride = obj_priv->stride; - goto err; - } + /* Change tiling parameter asynchronously to avoid + * gpu stalls. */ + obj_priv->fence_invalid = 1; + + i915_gem_release_mmap(obj); obj_priv->tiling_mode = args->tiling_mode; obj_priv->stride = args->stride; } -err: + drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); -- 1.6.6.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx