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.
v2: Reset obj_priv-fence_invalid in put_fence. No functional
change because put_fence checks whether there is actually a
fence allocated, so the put_fence in adjust_fencing won't harm.
But IMHO the code makes slightly more sense this way around.
Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch
---
drivers/gpu/drm/i915/i915_drv.h|6 ++
drivers/gpu/drm/i915/i915_gem.c| 10 ++
drivers/gpu/drm/i915/i915_gem_tiling.c | 26 ++
3 files changed, 22 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 asynchronously 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..023f4db 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,12 @@ 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;
+ }
+
if (!i915_gem_object_fence_offset_ok(obj, obj_priv-tiling_mode)) {
ret = i915_gem_object_unbind(obj);
if (ret != 0)
@@ -2621,6 +2629,8 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
struct drm_device *dev = obj-dev;
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
+ obj_priv-fence_invalid = 0;
+
if (obj_priv-fence_reg == I915_FENCE_REG_NONE)
return 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