diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 254eb0c46ae..ef14546fc08 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -51,7 +51,7 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, bool interruptible); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, - unsigned alignment); + unsigned alignment, bool mappable); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, @@ -1031,7 +1031,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, else if (obj_priv->tiling_mode == I915_TILING_NONE && obj_priv->gtt_space && obj->write_domain != I915_GEM_DOMAIN_CPU) { - ret = i915_gem_object_pin(obj, 0); + ret = i915_gem_object_pin(obj, 0, true); if (ret) goto out; @@ -1256,7 +1256,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Now bind it into the GTT if needed */ mutex_lock(&dev->struct_mutex); if (!obj_priv->gtt_space) { - ret = i915_gem_object_bind_to_gtt(obj, 0); + ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto unlock; @@ -1506,7 +1506,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, * initial fault faster and any subsequent flushing possible). */ if (!obj_priv->agp_mem) { - ret = i915_gem_object_bind_to_gtt(obj, 0); + ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto out; } @@ -2635,7 +2635,9 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj, * Finds free space in the GTT aperture and binds the object there. */ static int -i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) +i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, + unsigned alignment, + bool mappable) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -2659,22 +2661,42 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) /* If the object is bigger than the entire aperture, reject it early * before evicting everything in a vain attempt to find space. */ - if (obj->size > dev_priv->mm.gtt_total) { + if (obj->size > + (mappable ? 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; } search_free: - free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, - obj->size, alignment, 0); - if (free_space != NULL) - obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, - alignment); + if (mappable) + free_space = + drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, + obj->size, alignment, 0, + dev_priv->mm.gtt_mappable_end, + 0); + else + free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, + obj->size, alignment, 0); + + if (free_space != NULL) { + if (mappable) + obj_priv->gtt_space = + drm_mm_get_block_range_generic(free_space, + obj->size, + alignment, 0, + dev_priv->mm.gtt_mappable_end, + 0); + else + obj_priv->gtt_space = + drm_mm_get_block(free_space, obj->size, + alignment); + } if (obj_priv->gtt_space == NULL) { /* If the gtt is empty and we're still having trouble * fitting our object in, we're out of memory. */ - ret = i915_gem_evict_something(dev, obj->size, alignment, true); + ret = i915_gem_evict_something(dev, obj->size, alignment, + mappable); if (ret) return ret; @@ -2689,7 +2711,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) if (ret == -ENOMEM) { /* first try to clear up some space from the GTT */ ret = i915_gem_evict_something(dev, obj->size, - alignment, true); + alignment, mappable); if (ret) { /* now try to shrink everyone else */ if (gfpmask) { @@ -2719,7 +2741,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; - ret = i915_gem_evict_something(dev, obj->size, alignment, true); + ret = i915_gem_evict_something(dev, obj->size, alignment, + mappable); if (ret) return ret; @@ -3456,7 +3479,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, break; } - ret = i915_gem_object_pin(&obj->base, entry->alignment); + ret = i915_gem_object_pin(&obj->base, + entry->alignment, true); if (ret) break; @@ -4026,7 +4050,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, } int -i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) +i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, + bool mappable) { struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -4051,7 +4076,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) } if (obj_priv->gtt_space == NULL) { - ret = i915_gem_object_bind_to_gtt(obj, alignment); + ret = i915_gem_object_bind_to_gtt(obj, alignment, mappable); if (ret) return ret; } @@ -4133,7 +4158,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, obj_priv->user_pin_count++; obj_priv->pin_filp = file_priv; if (obj_priv->user_pin_count == 1) { - ret = i915_gem_object_pin(obj, args->alignment); + ret = i915_gem_object_pin(obj, args->alignment, true); if (ret) goto out; } @@ -4445,7 +4470,7 @@ i915_gem_init_pipe_control(struct drm_device *dev) obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - ret = i915_gem_object_pin(obj, 4096); + ret = i915_gem_object_pin(obj, 4096, true); if (ret) goto err_unref; |