diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-04-17 10:31:31 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-04-18 07:34:30 -0400 |
commit | 61050808bb019ebea966b7b5bfd357aaf219fb51 (patch) | |
tree | 72cc9ecdf833fc3bee5e66355acf985f1e3e964e /drivers/gpu/drm/i915/i915_gem.c | |
parent | 9ce079e4812c41c5f4ee9ea116c768b8939197d6 (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.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 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); |
51 | static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); | 51 | static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); |
52 | 52 | ||
53 | static void i915_gem_write_fence(struct drm_device *dev, int reg, | ||
54 | struct drm_i915_gem_object *obj); | ||
55 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | ||
56 | struct drm_i915_fence_reg *fence, | ||
57 | bool enable); | ||
58 | |||
53 | static int i915_gem_inactive_shrink(struct shrinker *shrinker, | 59 | static int i915_gem_inactive_shrink(struct shrinker *shrinker, |
54 | struct shrink_control *sc); | 60 | struct shrink_control *sc); |
55 | static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); | 61 | static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); |
56 | 62 | ||
63 | static 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 */ |
58 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, | 76 | static 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 | ||
2322 | static 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 | |||
2328 | static 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 | |||
2304 | static int | 2348 | static int |
2305 | i915_gem_object_flush_fence(struct drm_i915_gem_object *obj) | 2349 | i915_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) | |||
2339 | int | 2383 | int |
2340 | i915_gem_object_put_fence(struct drm_i915_gem_object *obj) | 2384 | i915_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 | } |