From patchwork Fri Mar 25 12:16:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 661821 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2PCGwII005098 for ; Fri, 25 Mar 2011 12:17:19 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7FB679E738 for ; Fri, 25 Mar 2011 05:16:57 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (server109-228-6-236.live-servers.net [109.228.6.236]) by gabe.freedesktop.org (Postfix) with ESMTP id 09E569E710 for ; Fri, 25 Mar 2011 05:16:35 -0700 (PDT) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.66.37; Received: from arrandale.alporthouse.com (unverified [78.156.66.37]) by fireflyinternet.com (Firefly Internet SMTP) with ESMTP id 30112274-1500050 for multiple; Fri, 25 Mar 2011 12:16:23 +0000 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Fri, 25 Mar 2011 12:16:25 +0000 Message-Id: <1301055385-4844-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1301045779-8076-1-git-send-email-chris@chris-wilson.co.uk> References: <1301045779-8076-1-git-send-email-chris@chris-wilson.co.uk> X-Originating-IP: 78.156.66.37 Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH] drm/i915: Round-up GTT allocations for unfenced surfaces to the next tile row X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 25 Mar 2011 12:17:19 +0000 (UTC) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 787c969..359ddce 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1183,6 +1183,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_size(struct drm_i915_gem_object *obj); +uint32_t i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj); /* i915_gem_gtt.c */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0012061..9144ff6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1426,6 +1426,55 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj) return i915_gem_get_gtt_size(obj); } +static u32 i915_gem_object_tiled_row_size(struct drm_i915_gem_object *obj) +{ + struct drm_device *dev = obj->base.dev; + int tile_height; + + 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; +} + +/** + * i915_gem_get_unfenced_gtt_size - return required GTT size for an + * unfenced object + * @obj: object to check + * + * Return the required GTT size for an object, only taking into account + * unfenced tiled surface requirements. + */ +uint32_t +i915_gem_get_unfenced_gtt_size(struct drm_i915_gem_object *obj) +{ + u32 unfenced_alignment; + + if (obj->tiling_mode == I915_TILING_NONE) + return obj->base.size; + + /* + * Current userspace will attempt to overallocate a bo so that it + * can be reused with another surface and so its size is unlikely + * to be an exact number of tile rows - but it promised never to + * access beyond the end of the last complete row. + * + * gen2 has a further restriction, in that it requires an even number + * of tiles rows. Userspace was not aware of this until recently + * and so violated its promise to always allocate enough pages + * for the hardware. In reply, we now always round up the GTT + * allocation to the next [even] tile row. + */ + unfenced_alignment = i915_gem_object_tiled_row_size(obj); + if (IS_GEN2(obj->base.dev)) + unfenced_alignment *= 2; + + return ALIGN(obj->base.size, unfenced_alignment); +} + /** * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an * unfenced object @@ -1438,7 +1487,6 @@ uint32_t i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) { struct drm_device *dev = obj->base.dev; - int tile_height; /* * Minimum alignment is 4k (GTT page size) for sane hw. @@ -1452,13 +1500,7 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) * edge of an even tile row (where tile rows are counted as if the bo is * placed in a fenced gtt region). */ - 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 2 * i915_gem_object_tiled_row_size(obj); } int @@ -2744,7 +2786,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, drm_i915_private_t *dev_priv = dev->dev_private; struct drm_mm_node *free_space; gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; - u32 size, fence_size, fence_alignment, unfenced_alignment; + u32 size, fence_size, fence_alignment; + u32 unfenced_size, unfenced_alignment; bool mappable, fenceable; int ret; @@ -2755,6 +2798,7 @@ 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_size = i915_gem_get_unfenced_gtt_size(obj); unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj); if (alignment == 0) @@ -2765,12 +2809,12 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, return -EINVAL; } - size = map_and_fenceable ? fence_size : obj->base.size; + size = map_and_fenceable ? fence_size : unfenced_size; /* If the object is bigger than the entire aperture, reject it early * before evicting everything in a vain attempt to find space. */ - if (obj->base.size > + if (size > (map_and_fenceable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { DRM_ERROR("Attempting to bind an object larger than the aperture\n"); return -E2BIG; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 281ad3d..e4d5c58 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -349,7 +349,10 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, if (!obj->map_and_fenceable) { u32 unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj); - if (obj->gtt_offset & (unfenced_alignment - 1)) + u32 unfenced_size = + i915_gem_get_unfenced_gtt_size(obj); + if (obj->gtt_space->size < unfenced_size || + obj->gtt_offset & (unfenced_alignment - 1)) ret = i915_gem_object_unbind(obj); }