diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-04-17 15:31:31 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-04-18 13:34:30 +0200 |
commit | 61050808bb019ebea966b7b5bfd357aaf219fb51 (patch) | |
tree | 72cc9ecdf833fc3bee5e66355acf985f1e3e964e /drivers | |
parent | 9ce079e4812c41c5f4ee9ea116c768b8939197d6 (diff) | |
download | op-kernel-dev-61050808bb019ebea966b7b5bfd357aaf219fb51.zip op-kernel-dev-61050808bb019ebea966b7b5bfd357aaf219fb51.tar.gz |
drm/i915: Refactor put_fence() to use the common fence writing routine
One clarification that we make is to the existing semantics of
obj->tiling_changed to only mean that we need to update an associated
fence register (including the NO_FENCE when executing an untiled but
fenced GPU command). If we do not have a fence register or pending
fenced GPU access for the object (after put_fence() for example), then
we can clear the tiling_changed flag as any fence will necessarily be
rewritten upon acquisition.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 199306d..3601b8b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -50,10 +50,28 @@ static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_file *file); static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); +static void i915_gem_write_fence(struct drm_device *dev, int reg, + struct drm_i915_gem_object *obj); +static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, + struct drm_i915_fence_reg *fence, + bool enable); + static int i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc); static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); +static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj) +{ + if (obj->tiling_mode) + i915_gem_release_mmap(obj); + + /* As we do not have an associated fence register, we will force + * a tiling change if we ever need to acquire one. + */ + obj->tiling_changed = false; + obj->fence_reg = I915_FENCE_REG_NONE; +} + /* some bookkeeping */ static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, size_t size) @@ -2301,6 +2319,32 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg, } } +static inline int fence_number(struct drm_i915_private *dev_priv, + struct drm_i915_fence_reg *fence) +{ + return fence - dev_priv->fence_regs; +} + +static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, + struct drm_i915_fence_reg *fence, + bool enable) +{ + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + int reg = fence_number(dev_priv, fence); + + i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); + + if (enable) { + obj->fence_reg = reg; + fence->obj = obj; + list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); + } else { + obj->fence_reg = I915_FENCE_REG_NONE; + fence->obj = NULL; + list_del_init(&fence->lru_list); + } +} + static int i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) { @@ -2339,24 +2383,20 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) int i915_gem_object_put_fence(struct drm_i915_gem_object *obj) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; int ret; - if (obj->tiling_mode) - i915_gem_release_mmap(obj); - ret = i915_gem_object_flush_fence(obj); if (ret) return ret; - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; - - WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count); - i915_gem_clear_fence_reg(obj->base.dev, - &dev_priv->fence_regs[obj->fence_reg]); + if (obj->fence_reg == I915_FENCE_REG_NONE) + return 0; - obj->fence_reg = I915_FENCE_REG_NONE; - } + i915_gem_object_update_fence(obj, + &dev_priv->fence_regs[obj->fence_reg], + false); + i915_gem_object_fence_lost(obj); return 0; } |