These operations are all quite similar and moving them to a separate function provides a clean split if we want to do something other than immediately binding the work into the ring. Signed-off-by: Ben Widawsky <ben at bwidawsk.net> --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 77 ++++++++++++++++-------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 99ebb36..35f6bf3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -827,6 +827,47 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev, return 0; } +/* Move the objects en-masse into the GTT, evicting if necessary. */ +static bool +prepare_objects(struct eb_objects *eb, struct drm_i915_gem_object *batch_obj, + u32 flags) +{ + bool need_relocs = (eb->args->flags & I915_EXEC_NO_RELOC) == 0; + int ret; + + ret = i915_gem_execbuffer_reserve(eb->ring, &eb->objects, &need_relocs); + if (ret) + return ret; + + /* The objects are in their final locations, apply the relocations. */ + if (need_relocs) + ret = i915_gem_execbuffer_relocate(eb); + if (ret) { + if (ret == -EFAULT) { + ret = i915_gem_execbuffer_relocate_slow(eb); + BUG_ON(!mutex_is_locked(&eb->ring->dev->struct_mutex)); + } + if (ret) + return ret; + } + + /* Set the pending read domains for the batch buffer to COMMAND */ + if (batch_obj->base.pending_write_domain) { + DRM_DEBUG("Attempting to use self-modifying batch buffer\n"); + return -EINVAL; + } + batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; + + /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure + * batch" bit. Hence we need to pin secure batches into the global gtt. + * hsw should have this fixed, but let's be paranoid and do it + * unconditionally for now. */ + if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) + i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); + + return i915_gem_execbuffer_move_to_gpu(eb->ring, &eb->objects); +} + static int i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_file *file, @@ -842,7 +883,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, u32 exec_start, exec_len; u32 mask, flags; int ret, mode, i; - bool need_relocs; if (!i915_gem_check_execbuffer(args)) return -EINVAL; @@ -987,40 +1027,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_i915_gem_object, exec_list); - /* Move the objects en-masse into the GTT, evicting if necessary. */ - need_relocs = (args->flags & I915_EXEC_NO_RELOC) == 0; - ret = i915_gem_execbuffer_reserve(ring, &eb->objects, &need_relocs); - if (ret) - goto err; - - /* The objects are in their final locations, apply the relocations. */ - if (need_relocs) - ret = i915_gem_execbuffer_relocate(eb); - if (ret) { - if (ret == -EFAULT) { - ret = i915_gem_execbuffer_relocate_slow(eb); - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - } - if (ret) - goto err; - } - - /* Set the pending read domains for the batch buffer to COMMAND */ - if (batch_obj->base.pending_write_domain) { - DRM_DEBUG("Attempting to use self-modifying batch buffer\n"); - ret = -EINVAL; - goto err; - } - batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; - - /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure - * batch" bit. Hence we need to pin secure batches into the global gtt. - * hsw should have this fixed, but let's be paranoid and do it - * unconditionally for now. */ - if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) - i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); - - ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->objects); + ret = prepare_objects(eb, batch_obj, flags); if (ret) goto err; -- 1.8.1.5