Pipelining tiling changes will complicate all places that need a correct fence register to be set up. So hide this complexity behind a small helper function.
i915_gem_object_get_fence loses all it's external callers by these changes, so convert it into a static function Signed-off-by: Daniel Vetter <daniel.vet...@ffwll.ch> --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 52 ++++++++++++++++++++++++++++----- drivers/gpu/drm/i915/intel_display.c | 16 ++-------- 3 files changed, 49 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 242993b..7aec3ec 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -918,7 +918,7 @@ void i915_gem_release_mmap(struct drm_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); uint32_t i915_get_gem_seqno(struct drm_device *dev); bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); -int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); +int i915_gem_object_adjust_fencing(struct drm_gem_object *obj); int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_work_handler(struct work_struct *work); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 47c46ed..8e73a12 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -974,6 +974,10 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); else if (obj_priv->tiling_mode == I915_TILING_NONE && dev->gtt_total != 0) { + ret = i915_gem_object_adjust_fencing(obj); + if (ret != 0) + return ret; + ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv); if (ret == -EFAULT) { ret = i915_gem_gtt_pwrite_slow(dev, obj, args, @@ -1191,12 +1195,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) goto unlock; } - /* Need a new fence register? */ - if (obj_priv->tiling_mode != I915_TILING_NONE) { - ret = i915_gem_object_get_fence_reg(obj); - if (ret) - goto unlock; - } + ret = i915_gem_object_adjust_fencing(obj); + if (ret) + goto unlock; pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + page_offset; @@ -2475,7 +2476,7 @@ static int i915_find_fence_reg(struct drm_device *dev) * It then sets up the reg based on the object's properties: address, pitch * and tiling format. */ -int +static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; @@ -2536,6 +2537,41 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) } /** + * i915_gem_object_adjust_fencing - ensure correct fencing for an object + * @obj: object to map through a fence reg + * + * Tiling changes may be delayed untill fenced access is actually needed. + * Batchbuffer submitted via execbuf2 may not need a fence, so delaying + * gtt remapping and fence register changes (which all stall the gpu) as + * long as possible is beneficial. + * + * This function ensures that all delayed operations have been carried out and + * the object can be correctly accessed via fences. + */ +int +i915_gem_object_adjust_fencing(struct drm_gem_object *obj) +{ + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + int ret; + + if (!i915_gem_object_fence_offset_ok(obj, obj_priv->tiling_mode)) { + ret = i915_gem_object_unbind(obj); + if (ret != 0) + return ret; + ret = i915_gem_object_bind_to_gtt(obj, 0); + if (ret != 0) + return ret; + } + + if (obj_priv->tiling_mode != I915_TILING_NONE) { + ret = i915_gem_object_get_fence_reg(obj); + if (ret != 0) + return ret; + } + return 0; +} + +/** * i915_gem_clear_fence_reg - clear out fence register info * @obj: object to clear * @@ -3309,7 +3345,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, * properly handle blits to/from tiled surfaces. */ if (need_fence) { - ret = i915_gem_object_get_fence_reg(obj); + ret = i915_gem_object_adjust_fencing(obj); if (ret != 0) { if (ret != -EBUSY && ret != -ERESTARTSYS) DRM_ERROR("Failure to install fence: %d\n", diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3836f56..56b673d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1249,18 +1249,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) if (ret != 0) return ret; - /* Install a fence for tiled scan-out. Pre-i965 always needs a - * fence, whereas 965+ only requires a fence if using - * framebuffer compression. For simplicity, we always install - * a fence as the cost is not that onerous. - */ - if (obj_priv->fence_reg == I915_FENCE_REG_NONE && - obj_priv->tiling_mode != I915_TILING_NONE) { - ret = i915_gem_object_get_fence_reg(obj); - if (ret != 0) { - i915_gem_object_unpin(obj); - return ret; - } + ret = i915_gem_object_adjust_fencing(obj); + if (ret != 0) { + i915_gem_object_unpin(obj); + return ret; } return 0; -- 1.6.6.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx