aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-04-17 10:31:31 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-04-18 07:34:30 -0400
commit61050808bb019ebea966b7b5bfd357aaf219fb51 (patch)
tree72cc9ecdf833fc3bee5e66355acf985f1e3e964e /drivers/gpu/drm/i915/i915_gem.c
parent9ce079e4812c41c5f4ee9ea116c768b8939197d6 (diff)
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/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c62
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 199306dfca85..3601b8b6e45f 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,
50 struct drm_file *file); 50 struct drm_file *file);
51static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); 51static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj);
52 52
53static void i915_gem_write_fence(struct drm_device *dev, int reg,
54 struct drm_i915_gem_object *obj);
55static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
56 struct drm_i915_fence_reg *fence,
57 bool enable);
58
53static int i915_gem_inactive_shrink(struct shrinker *shrinker, 59static int i915_gem_inactive_shrink(struct shrinker *shrinker,
54 struct shrink_control *sc); 60 struct shrink_control *sc);
55static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); 61static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
56 62
63static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
64{
65 if (obj->tiling_mode)
66 i915_gem_release_mmap(obj);
67
68 /* As we do not have an associated fence register, we will force
69 * a tiling change if we ever need to acquire one.
70 */
71 obj->tiling_changed = false;
72 obj->fence_reg = I915_FENCE_REG_NONE;
73}
74
57/* some bookkeeping */ 75/* some bookkeeping */
58static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, 76static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv,
59 size_t size) 77 size_t size)
@@ -2301,6 +2319,32 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg,
2301 } 2319 }
2302} 2320}
2303 2321
2322static inline int fence_number(struct drm_i915_private *dev_priv,
2323 struct drm_i915_fence_reg *fence)
2324{
2325 return fence - dev_priv->fence_regs;
2326}
2327
2328static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
2329 struct drm_i915_fence_reg *fence,
2330 bool enable)
2331{
2332 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
2333 int reg = fence_number(dev_priv, fence);
2334
2335 i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
2336
2337 if (enable) {
2338 obj->fence_reg = reg;
2339 fence->obj = obj;
2340 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
2341 } else {
2342 obj->fence_reg = I915_FENCE_REG_NONE;
2343 fence->obj = NULL;
2344 list_del_init(&fence->lru_list);
2345 }
2346}
2347
2304static int 2348static int
2305i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) 2349i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
2306{ 2350{
@@ -2339,24 +2383,20 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
2339int 2383int
2340i915_gem_object_put_fence(struct drm_i915_gem_object *obj) 2384i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
2341{ 2385{
2386 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
2342 int ret; 2387 int ret;
2343 2388
2344 if (obj->tiling_mode)
2345 i915_gem_release_mmap(obj);
2346
2347 ret = i915_gem_object_flush_fence(obj); 2389 ret = i915_gem_object_flush_fence(obj);
2348 if (ret) 2390 if (ret)
2349 return ret; 2391 return ret;
2350 2392
2351 if (obj->fence_reg != I915_FENCE_REG_NONE) { 2393 if (obj->fence_reg == I915_FENCE_REG_NONE)
2352 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 2394 return 0;
2353
2354 WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count);
2355 i915_gem_clear_fence_reg(obj->base.dev,
2356 &dev_priv->fence_regs[obj->fence_reg]);
2357 2395
2358 obj->fence_reg = I915_FENCE_REG_NONE; 2396 i915_gem_object_update_fence(obj,
2359 } 2397 &dev_priv->fence_regs[obj->fence_reg],
2398 false);
2399 i915_gem_object_fence_lost(obj);
2360 2400
2361 return 0; 2401 return 0;
2362} 2402}