* Kill unused fence pipelining
@ 2012-04-17 14:31 Chris Wilson
2012-04-17 14:31 ` [PATCH 01/12] drm/i915: Remove the pipelined parameter from get_fence() Chris Wilson
` (11 more replies)
0 siblings, 12 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
Since we have never succeeded in making the pipelined fence updates
stable and it appears we never will, delete the dead code.
-Chris
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 01/12] drm/i915: Remove the pipelined parameter from get_fence()
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 02/12] drm/i915: Remove fence pipelining Chris Wilson
` (10 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
We never succeeded in getting pipelined fencing to work (unresolved
spurious GPU hangs), so begin the process of dismantling and removal
the broken code.
Step 1 is the removal of the pipeline parameter to get_fence().
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 3 +--
drivers/gpu/drm/i915/i915_gem.c | 7 +++----
drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +-
drivers/gpu/drm/i915/intel_display.c | 2 +-
4 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 422f424..e99a02a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1255,8 +1255,7 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2)
u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring);
-int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *pipelined);
+int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj);
int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
static inline bool
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index aa44ff2..40e0808 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1079,7 +1079,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
if (!obj->has_global_gtt_mapping)
i915_gem_gtt_bind_object(obj, obj->cache_level);
- ret = i915_gem_object_get_fence(obj, NULL);
+ ret = i915_gem_object_get_fence(obj);
if (ret)
goto unlock;
@@ -2453,7 +2453,6 @@ i915_find_fence_reg(struct drm_device *dev,
/**
* i915_gem_object_get_fence - set up fencing for an object
* @obj: object to map through a fence reg
- * @pipelined: ring on which to queue the change, or NULL for CPU access
*
* When mapping objects through the GTT, userspace wants to be able to write
* to them without having to worry about swizzling if the object is tiled.
@@ -2466,11 +2465,11 @@ i915_find_fence_reg(struct drm_device *dev,
* For an untiled surface, this removes any existing fence.
*/
int
-i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *pipelined)
+i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_ring_buffer *pipelined;
struct drm_i915_fence_reg *reg;
int ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 2a24d0c..b5262fd 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -530,7 +530,7 @@ pin_and_fence_object(struct drm_i915_gem_object *obj,
if (has_fenced_gpu_access) {
if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
- ret = i915_gem_object_get_fence(obj, ring);
+ ret = i915_gem_object_get_fence(obj);
if (ret)
goto err_unpin;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7506a72..95d7713 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2151,7 +2151,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
* framebuffer compression. For simplicity, we always install
* a fence as the cost is not that onerous.
*/
- ret = i915_gem_object_get_fence(obj, pipelined);
+ ret = i915_gem_object_get_fence(obj);
if (ret)
goto err_unpin;
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 02/12] drm/i915: Remove fence pipelining
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
2012-04-17 14:31 ` [PATCH 01/12] drm/i915: Remove the pipelined parameter from get_fence() Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 03/12] drm/i915: Remove unused ring->setup_seqno Chris Wilson
` (9 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
Step 2 is then to replace the pipelined parameter with NULL and perform
constant folding to remove dead code.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 155 +++++++++------------------------------
1 file changed, 36 insertions(+), 119 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 40e0808..5a9d90f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2166,8 +2166,7 @@ int i915_gpu_idle(struct drm_device *dev, bool do_retire)
return 0;
}
-static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *pipelined)
+static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2185,26 +2184,12 @@ static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj,
val |= 1 << I965_FENCE_TILING_Y_SHIFT;
val |= I965_FENCE_REG_VALID;
- if (pipelined) {
- int ret = intel_ring_begin(pipelined, 6);
- if (ret)
- return ret;
-
- intel_ring_emit(pipelined, MI_NOOP);
- intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2));
- intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8);
- intel_ring_emit(pipelined, (u32)val);
- intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8 + 4);
- intel_ring_emit(pipelined, (u32)(val >> 32));
- intel_ring_advance(pipelined);
- } else
- I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + regnum * 8, val);
+ I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + regnum * 8, val);
return 0;
}
-static int i965_write_fence_reg(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *pipelined)
+static int i965_write_fence_reg(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2220,26 +2205,12 @@ static int i965_write_fence_reg(struct drm_i915_gem_object *obj,
val |= 1 << I965_FENCE_TILING_Y_SHIFT;
val |= I965_FENCE_REG_VALID;
- if (pipelined) {
- int ret = intel_ring_begin(pipelined, 6);
- if (ret)
- return ret;
-
- intel_ring_emit(pipelined, MI_NOOP);
- intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2));
- intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8);
- intel_ring_emit(pipelined, (u32)val);
- intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8 + 4);
- intel_ring_emit(pipelined, (u32)(val >> 32));
- intel_ring_advance(pipelined);
- } else
- I915_WRITE64(FENCE_REG_965_0 + regnum * 8, val);
+ I915_WRITE64(FENCE_REG_965_0 + regnum * 8, val);
return 0;
}
-static int i915_write_fence_reg(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *pipelined)
+static int i915_write_fence_reg(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2276,24 +2247,12 @@ static int i915_write_fence_reg(struct drm_i915_gem_object *obj,
else
fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4;
- if (pipelined) {
- int ret = intel_ring_begin(pipelined, 4);
- if (ret)
- return ret;
-
- intel_ring_emit(pipelined, MI_NOOP);
- intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(pipelined, fence_reg);
- intel_ring_emit(pipelined, val);
- intel_ring_advance(pipelined);
- } else
- I915_WRITE(fence_reg, val);
+ I915_WRITE(fence_reg, val);
return 0;
}
-static int i830_write_fence_reg(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *pipelined)
+static int i830_write_fence_reg(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2319,18 +2278,7 @@ static int i830_write_fence_reg(struct drm_i915_gem_object *obj,
val |= pitch_val << I830_FENCE_PITCH_SHIFT;
val |= I830_FENCE_REG_VALID;
- if (pipelined) {
- int ret = intel_ring_begin(pipelined, 4);
- if (ret)
- return ret;
-
- intel_ring_emit(pipelined, MI_NOOP);
- intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(pipelined, FENCE_REG_830_0 + regnum*4);
- intel_ring_emit(pipelined, val);
- intel_ring_advance(pipelined);
- } else
- I915_WRITE(FENCE_REG_830_0 + regnum * 4, val);
+ I915_WRITE(FENCE_REG_830_0 + regnum * 4, val);
return 0;
}
@@ -2341,8 +2289,7 @@ static bool ring_passed_seqno(struct intel_ring_buffer *ring, u32 seqno)
}
static int
-i915_gem_object_flush_fence(struct drm_i915_gem_object *obj,
- struct intel_ring_buffer *pipelined)
+i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
{
int ret;
@@ -2357,7 +2304,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj,
obj->fenced_gpu_access = false;
}
- if (obj->last_fenced_seqno && pipelined != obj->last_fenced_ring) {
+ if (obj->last_fenced_seqno && NULL != obj->last_fenced_ring) {
if (!ring_passed_seqno(obj->last_fenced_ring,
obj->last_fenced_seqno)) {
ret = i915_wait_request(obj->last_fenced_ring,
@@ -2388,7 +2335,7 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
if (obj->tiling_mode)
i915_gem_release_mmap(obj);
- ret = i915_gem_object_flush_fence(obj, NULL);
+ ret = i915_gem_object_flush_fence(obj);
if (ret)
return ret;
@@ -2406,8 +2353,7 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
}
static struct drm_i915_fence_reg *
-i915_find_fence_reg(struct drm_device *dev,
- struct intel_ring_buffer *pipelined)
+i915_find_fence_reg(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_fence_reg *reg, *first, *avail;
@@ -2436,9 +2382,7 @@ i915_find_fence_reg(struct drm_device *dev,
if (first == NULL)
first = reg;
- if (!pipelined ||
- !reg->obj->last_fenced_ring ||
- reg->obj->last_fenced_ring == pipelined) {
+ if (reg->obj->last_fenced_ring == NULL) {
avail = reg;
break;
}
@@ -2469,67 +2413,46 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *pipelined;
struct drm_i915_fence_reg *reg;
int ret;
if (obj->tiling_mode == I915_TILING_NONE)
return i915_gem_object_put_fence(obj);
- /* XXX disable pipelining. There are bugs. Shocking. */
- pipelined = NULL;
-
/* Just update our place in the LRU if our fence is getting reused. */
if (obj->fence_reg != I915_FENCE_REG_NONE) {
reg = &dev_priv->fence_regs[obj->fence_reg];
list_move_tail(®->lru_list, &dev_priv->mm.fence_list);
if (obj->tiling_changed) {
- ret = i915_gem_object_flush_fence(obj, pipelined);
+ ret = i915_gem_object_flush_fence(obj);
if (ret)
return ret;
- if (!obj->fenced_gpu_access && !obj->last_fenced_seqno)
- pipelined = NULL;
-
- if (pipelined) {
- reg->setup_seqno =
- i915_gem_next_request_seqno(pipelined);
- obj->last_fenced_seqno = reg->setup_seqno;
- obj->last_fenced_ring = pipelined;
- }
-
goto update;
}
- if (!pipelined) {
- if (reg->setup_seqno) {
- if (!ring_passed_seqno(obj->last_fenced_ring,
- reg->setup_seqno)) {
- ret = i915_wait_request(obj->last_fenced_ring,
- reg->setup_seqno,
- true);
- if (ret)
- return ret;
- }
-
- reg->setup_seqno = 0;
+ if (reg->setup_seqno) {
+ if (!ring_passed_seqno(obj->last_fenced_ring,
+ reg->setup_seqno)) {
+ ret = i915_wait_request(obj->last_fenced_ring,
+ reg->setup_seqno,
+ true);
+ if (ret)
+ return ret;
}
- } else if (obj->last_fenced_ring &&
- obj->last_fenced_ring != pipelined) {
- ret = i915_gem_object_flush_fence(obj, pipelined);
- if (ret)
- return ret;
+
+ reg->setup_seqno = 0;
}
return 0;
}
- reg = i915_find_fence_reg(dev, pipelined);
+ reg = i915_find_fence_reg(dev);
if (reg == NULL)
return -EDEADLK;
- ret = i915_gem_object_flush_fence(obj, pipelined);
+ ret = i915_gem_object_flush_fence(obj);
if (ret)
return ret;
@@ -2541,31 +2464,25 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
if (old->tiling_mode)
i915_gem_release_mmap(old);
- ret = i915_gem_object_flush_fence(old, pipelined);
+ ret = i915_gem_object_flush_fence(old);
if (ret) {
drm_gem_object_unreference(&old->base);
return ret;
}
- if (old->last_fenced_seqno == 0 && obj->last_fenced_seqno == 0)
- pipelined = NULL;
-
old->fence_reg = I915_FENCE_REG_NONE;
- old->last_fenced_ring = pipelined;
- old->last_fenced_seqno =
- pipelined ? i915_gem_next_request_seqno(pipelined) : 0;
+ old->last_fenced_ring = NULL;
+ old->last_fenced_seqno = 0;
drm_gem_object_unreference(&old->base);
- } else if (obj->last_fenced_seqno == 0)
- pipelined = NULL;
+ }
reg->obj = obj;
list_move_tail(®->lru_list, &dev_priv->mm.fence_list);
obj->fence_reg = reg - dev_priv->fence_regs;
- obj->last_fenced_ring = pipelined;
+ obj->last_fenced_ring = NULL;
- reg->setup_seqno =
- pipelined ? i915_gem_next_request_seqno(pipelined) : 0;
+ reg->setup_seqno = 0;
obj->last_fenced_seqno = reg->setup_seqno;
update:
@@ -2573,17 +2490,17 @@ update:
switch (INTEL_INFO(dev)->gen) {
case 7:
case 6:
- ret = sandybridge_write_fence_reg(obj, pipelined);
+ ret = sandybridge_write_fence_reg(obj);
break;
case 5:
case 4:
- ret = i965_write_fence_reg(obj, pipelined);
+ ret = i965_write_fence_reg(obj);
break;
case 3:
- ret = i915_write_fence_reg(obj, pipelined);
+ ret = i915_write_fence_reg(obj);
break;
case 2:
- ret = i830_write_fence_reg(obj, pipelined);
+ ret = i830_write_fence_reg(obj);
break;
}
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 03/12] drm/i915: Remove unused ring->setup_seqno
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
2012-04-17 14:31 ` [PATCH 01/12] drm/i915: Remove the pipelined parameter from get_fence() Chris Wilson
2012-04-17 14:31 ` [PATCH 02/12] drm/i915: Remove fence pipelining Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 04/12] drm/i915: Discard the unused obj->last_fenced_ring Chris Wilson
` (8 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
As we now no longer track a pipelined fence change, we never use
ring->setup_seqno and can kill it.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 1 -
drivers/gpu/drm/i915/i915_gem.c | 17 -----------------
2 files changed, 18 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e99a02a..735af61 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -146,7 +146,6 @@ struct drm_i915_master_private {
struct drm_i915_fence_reg {
struct list_head lru_list;
struct drm_i915_gem_object *obj;
- uint32_t setup_seqno;
int pin_count;
};
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 5a9d90f..3a091f5 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2432,19 +2432,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
goto update;
}
- if (reg->setup_seqno) {
- if (!ring_passed_seqno(obj->last_fenced_ring,
- reg->setup_seqno)) {
- ret = i915_wait_request(obj->last_fenced_ring,
- reg->setup_seqno,
- true);
- if (ret)
- return ret;
- }
-
- reg->setup_seqno = 0;
- }
-
return 0;
}
@@ -2482,9 +2469,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
obj->fence_reg = reg - dev_priv->fence_regs;
obj->last_fenced_ring = NULL;
- reg->setup_seqno = 0;
- obj->last_fenced_seqno = reg->setup_seqno;
-
update:
obj->tiling_changed = false;
switch (INTEL_INFO(dev)->gen) {
@@ -2543,7 +2527,6 @@ i915_gem_clear_fence_reg(struct drm_device *dev,
list_del_init(®->lru_list);
reg->obj = NULL;
- reg->setup_seqno = 0;
reg->pin_count = 0;
}
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 04/12] drm/i915: Discard the unused obj->last_fenced_ring
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (2 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 03/12] drm/i915: Remove unused ring->setup_seqno Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 05/12] drm/i915: Simplify fence finding Chris Wilson
` (7 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
As we now never pipeline a fence update, obj->last_fenced_ring is always
the same as the obj->ring whenever obj->last_fenced_seqno is active, so
remove it.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 5 ++---
drivers/gpu/drm/i915/i915_gem.c | 16 +++++-----------
2 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 735af61..8c32ada 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -930,13 +930,12 @@ struct drm_i915_gem_object {
*/
uint32_t gtt_offset;
- /** Breadcrumb of last rendering to the buffer. */
- uint32_t last_rendering_seqno;
struct intel_ring_buffer *ring;
+ /** Breadcrumb of last rendering to the buffer. */
+ uint32_t last_rendering_seqno;
/** Breadcrumb of last fenced GPU access to the buffer. */
uint32_t last_fenced_seqno;
- struct intel_ring_buffer *last_fenced_ring;
/** Current tiling stride for the object, if it's tiled. */
uint32_t stride;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3a091f5..b25d229 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1398,7 +1398,6 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
if (obj->fenced_gpu_access) {
obj->last_fenced_seqno = seqno;
- obj->last_fenced_ring = ring;
/* Bump MRU to take account of the delayed flush */
if (obj->fence_reg != I915_FENCE_REG_NONE) {
@@ -1445,7 +1444,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
BUG_ON(!list_empty(&obj->gpu_write_list));
BUG_ON(!obj->active);
obj->ring = NULL;
- obj->last_fenced_ring = NULL;
i915_gem_object_move_off_active(obj);
obj->fenced_gpu_access = false;
@@ -1650,7 +1648,6 @@ static void i915_gem_reset_fences(struct drm_device *dev)
reg->obj->fence_reg = I915_FENCE_REG_NONE;
reg->obj->fenced_gpu_access = false;
reg->obj->last_fenced_seqno = 0;
- reg->obj->last_fenced_ring = NULL;
i915_gem_clear_fence_reg(dev, reg);
}
}
@@ -2295,7 +2292,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
if (obj->fenced_gpu_access) {
if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
- ret = i915_gem_flush_ring(obj->last_fenced_ring,
+ ret = i915_gem_flush_ring(obj->ring,
0, obj->base.write_domain);
if (ret)
return ret;
@@ -2304,10 +2301,10 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
obj->fenced_gpu_access = false;
}
- if (obj->last_fenced_seqno && NULL != obj->last_fenced_ring) {
- if (!ring_passed_seqno(obj->last_fenced_ring,
+ if (obj->last_fenced_seqno) {
+ if (!ring_passed_seqno(obj->ring,
obj->last_fenced_seqno)) {
- ret = i915_wait_request(obj->last_fenced_ring,
+ ret = i915_wait_request(obj->ring,
obj->last_fenced_seqno,
true);
if (ret)
@@ -2315,7 +2312,6 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
}
obj->last_fenced_seqno = 0;
- obj->last_fenced_ring = NULL;
}
/* Ensure that all CPU reads are completed before installing a fence
@@ -2382,7 +2378,7 @@ i915_find_fence_reg(struct drm_device *dev)
if (first == NULL)
first = reg;
- if (reg->obj->last_fenced_ring == NULL) {
+ if (reg->obj->last_fenced_seqno == 0) {
avail = reg;
break;
}
@@ -2458,7 +2454,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
}
old->fence_reg = I915_FENCE_REG_NONE;
- old->last_fenced_ring = NULL;
old->last_fenced_seqno = 0;
drm_gem_object_unreference(&old->base);
@@ -2467,7 +2462,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
reg->obj = obj;
list_move_tail(®->lru_list, &dev_priv->mm.fence_list);
obj->fence_reg = reg - dev_priv->fence_regs;
- obj->last_fenced_ring = NULL;
update:
obj->tiling_changed = false;
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 05/12] drm/i915: Simplify fence finding
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (3 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 04/12] drm/i915: Discard the unused obj->last_fenced_ring Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 06/12] drm/i915: Remove the unsightly "optimisation" from flush_fence() Chris Wilson
` (6 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
As the fences are stored in LRU order, we can simply reuse the oldest if
we do not have an unused register.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b25d229..f7cd3461 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2352,7 +2352,7 @@ static struct drm_i915_fence_reg *
i915_find_fence_reg(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_i915_fence_reg *reg, *first, *avail;
+ struct drm_i915_fence_reg *reg, *avail;
int i;
/* First try to find a free reg */
@@ -2370,24 +2370,14 @@ i915_find_fence_reg(struct drm_device *dev)
return NULL;
/* None available, try to steal one or wait for a user to finish */
- avail = first = NULL;
list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) {
if (reg->pin_count)
continue;
- if (first == NULL)
- first = reg;
-
- if (reg->obj->last_fenced_seqno == 0) {
- avail = reg;
- break;
- }
+ return reg;
}
- if (avail == NULL)
- avail = first;
-
- return avail;
+ return NULL;
}
/**
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 06/12] drm/i915: Remove the unsightly "optimisation" from flush_fence()
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (4 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 05/12] drm/i915: Simplify fence finding Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 07/12] drm/i915: Prepare to consolidate fence writing Chris Wilson
` (5 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
As i915_wait_request() will first check for an already passed seqno,
doing it also in the caller is a waste of space for a cold path.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 18 +++++-------------
1 file changed, 5 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f7cd3461..bac3570 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2280,11 +2280,6 @@ static int i830_write_fence_reg(struct drm_i915_gem_object *obj)
return 0;
}
-static bool ring_passed_seqno(struct intel_ring_buffer *ring, u32 seqno)
-{
- return i915_seqno_passed(ring->get_seqno(ring), seqno);
-}
-
static int
i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
{
@@ -2302,14 +2297,11 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
}
if (obj->last_fenced_seqno) {
- if (!ring_passed_seqno(obj->ring,
- obj->last_fenced_seqno)) {
- ret = i915_wait_request(obj->ring,
- obj->last_fenced_seqno,
- true);
- if (ret)
- return ret;
- }
+ ret = i915_wait_request(obj->ring,
+ obj->last_fenced_seqno,
+ true);
+ if (ret)
+ return ret;
obj->last_fenced_seqno = 0;
}
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 07/12] drm/i915: Prepare to consolidate fence writing
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (5 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 06/12] drm/i915: Remove the unsightly "optimisation" from flush_fence() Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 08/12] drm/i915: Refactor put_fence() to use the common fence writing routine Chris Wilson
` (4 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
Update the existing architecture specific fence writing routines to
either update the fence to point to a tiled object or to clear them in
preparation to remove the other fence writing routes.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 211 ++++++++++++++++++++-------------------
1 file changed, 108 insertions(+), 103 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index bac3570..199306d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2163,121 +2163,142 @@ int i915_gpu_idle(struct drm_device *dev, bool do_retire)
return 0;
}
-static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj)
+static void sandybridge_write_fence_reg(struct drm_device *dev, int reg,
+ struct drm_i915_gem_object *obj)
{
- struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- u32 size = obj->gtt_space->size;
- int regnum = obj->fence_reg;
uint64_t val;
- val = (uint64_t)((obj->gtt_offset + size - 4096) &
- 0xfffff000) << 32;
- val |= obj->gtt_offset & 0xfffff000;
- val |= (uint64_t)((obj->stride / 128) - 1) <<
- SANDYBRIDGE_FENCE_PITCH_SHIFT;
+ if (obj) {
+ u32 size = obj->gtt_space->size;
- if (obj->tiling_mode == I915_TILING_Y)
- val |= 1 << I965_FENCE_TILING_Y_SHIFT;
- val |= I965_FENCE_REG_VALID;
+ val = (uint64_t)((obj->gtt_offset + size - 4096) &
+ 0xfffff000) << 32;
+ val |= obj->gtt_offset & 0xfffff000;
+ val |= (uint64_t)((obj->stride / 128) - 1) <<
+ SANDYBRIDGE_FENCE_PITCH_SHIFT;
- I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + regnum * 8, val);
+ if (obj->tiling_mode == I915_TILING_Y)
+ val |= 1 << I965_FENCE_TILING_Y_SHIFT;
+ val |= I965_FENCE_REG_VALID;
+ } else
+ val = 0;
- return 0;
+ I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + reg * 8, val);
+ POSTING_READ(FENCE_REG_SANDYBRIDGE_0 + reg * 8);
}
-static int i965_write_fence_reg(struct drm_i915_gem_object *obj)
+static void i965_write_fence_reg(struct drm_device *dev, int reg,
+ struct drm_i915_gem_object *obj)
{
- struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- u32 size = obj->gtt_space->size;
- int regnum = obj->fence_reg;
uint64_t val;
- val = (uint64_t)((obj->gtt_offset + size - 4096) &
- 0xfffff000) << 32;
- val |= obj->gtt_offset & 0xfffff000;
- val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT;
- if (obj->tiling_mode == I915_TILING_Y)
- val |= 1 << I965_FENCE_TILING_Y_SHIFT;
- val |= I965_FENCE_REG_VALID;
+ if (obj) {
+ u32 size = obj->gtt_space->size;
- I915_WRITE64(FENCE_REG_965_0 + regnum * 8, val);
+ val = (uint64_t)((obj->gtt_offset + size - 4096) &
+ 0xfffff000) << 32;
+ val |= obj->gtt_offset & 0xfffff000;
+ val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT;
+ if (obj->tiling_mode == I915_TILING_Y)
+ val |= 1 << I965_FENCE_TILING_Y_SHIFT;
+ val |= I965_FENCE_REG_VALID;
+ } else
+ val = 0;
- return 0;
+ I915_WRITE64(FENCE_REG_965_0 + reg * 8, val);
+ POSTING_READ(FENCE_REG_965_0 + reg * 8);
}
-static int i915_write_fence_reg(struct drm_i915_gem_object *obj)
+static void i915_write_fence_reg(struct drm_device *dev, int reg,
+ struct drm_i915_gem_object *obj)
{
- struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- u32 size = obj->gtt_space->size;
- u32 fence_reg, val, pitch_val;
- int tile_width;
-
- if (WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) ||
- (size & -size) != size ||
- (obj->gtt_offset & (size - 1)),
- "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n",
- obj->gtt_offset, obj->map_and_fenceable, size))
- return -EINVAL;
+ u32 val;
- if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
- tile_width = 128;
- else
- tile_width = 512;
-
- /* Note: pitch better be a power of two tile widths */
- pitch_val = obj->stride / tile_width;
- pitch_val = ffs(pitch_val) - 1;
-
- val = obj->gtt_offset;
- if (obj->tiling_mode == I915_TILING_Y)
- val |= 1 << I830_FENCE_TILING_Y_SHIFT;
- val |= I915_FENCE_SIZE_BITS(size);
- val |= pitch_val << I830_FENCE_PITCH_SHIFT;
- val |= I830_FENCE_REG_VALID;
-
- fence_reg = obj->fence_reg;
- if (fence_reg < 8)
- fence_reg = FENCE_REG_830_0 + fence_reg * 4;
- else
- fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4;
+ if (obj) {
+ u32 size = obj->gtt_space->size;
+ int pitch_val;
+ int tile_width;
- I915_WRITE(fence_reg, val);
+ WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) ||
+ (size & -size) != size ||
+ (obj->gtt_offset & (size - 1)),
+ "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n",
+ obj->gtt_offset, obj->map_and_fenceable, size);
- return 0;
+ if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
+ tile_width = 128;
+ else
+ tile_width = 512;
+
+ /* Note: pitch better be a power of two tile widths */
+ pitch_val = obj->stride / tile_width;
+ pitch_val = ffs(pitch_val) - 1;
+
+ val = obj->gtt_offset;
+ if (obj->tiling_mode == I915_TILING_Y)
+ val |= 1 << I830_FENCE_TILING_Y_SHIFT;
+ val |= I915_FENCE_SIZE_BITS(size);
+ val |= pitch_val << I830_FENCE_PITCH_SHIFT;
+ val |= I830_FENCE_REG_VALID;
+ } else
+ val = 0;
+
+ if (reg < 8)
+ reg = FENCE_REG_830_0 + reg * 4;
+ else
+ reg = FENCE_REG_945_8 + (reg - 8) * 4;
+
+ I915_WRITE(reg, val);
+ POSTING_READ(reg);
}
-static int i830_write_fence_reg(struct drm_i915_gem_object *obj)
+static void i830_write_fence_reg(struct drm_device *dev, int reg,
+ struct drm_i915_gem_object *obj)
{
- struct drm_device *dev = obj->base.dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- u32 size = obj->gtt_space->size;
- int regnum = obj->fence_reg;
uint32_t val;
- uint32_t pitch_val;
-
- if (WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) ||
- (size & -size) != size ||
- (obj->gtt_offset & (size - 1)),
- "object 0x%08x not 512K or pot-size 0x%08x aligned\n",
- obj->gtt_offset, size))
- return -EINVAL;
- pitch_val = obj->stride / 128;
- pitch_val = ffs(pitch_val) - 1;
-
- val = obj->gtt_offset;
- if (obj->tiling_mode == I915_TILING_Y)
- val |= 1 << I830_FENCE_TILING_Y_SHIFT;
- val |= I830_FENCE_SIZE_BITS(size);
- val |= pitch_val << I830_FENCE_PITCH_SHIFT;
- val |= I830_FENCE_REG_VALID;
+ if (obj) {
+ u32 size = obj->gtt_space->size;
+ uint32_t pitch_val;
+
+ WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) ||
+ (size & -size) != size ||
+ (obj->gtt_offset & (size - 1)),
+ "object 0x%08x not 512K or pot-size 0x%08x aligned\n",
+ obj->gtt_offset, size);
+
+ pitch_val = obj->stride / 128;
+ pitch_val = ffs(pitch_val) - 1;
+
+ val = obj->gtt_offset;
+ if (obj->tiling_mode == I915_TILING_Y)
+ val |= 1 << I830_FENCE_TILING_Y_SHIFT;
+ val |= I830_FENCE_SIZE_BITS(size);
+ val |= pitch_val << I830_FENCE_PITCH_SHIFT;
+ val |= I830_FENCE_REG_VALID;
+ } else
+ val = 0;
- I915_WRITE(FENCE_REG_830_0 + regnum * 4, val);
+ I915_WRITE(FENCE_REG_830_0 + reg * 4, val);
+ POSTING_READ(FENCE_REG_830_0 + reg * 4);
+}
- return 0;
+static void i915_gem_write_fence(struct drm_device *dev, int reg,
+ struct drm_i915_gem_object *obj)
+{
+ switch (INTEL_INFO(dev)->gen) {
+ case 7:
+ case 6: sandybridge_write_fence_reg(dev, reg, obj); break;
+ case 5:
+ case 4: i965_write_fence_reg(dev, reg, obj); break;
+ case 3: i915_write_fence_reg(dev, reg, obj); break;
+ case 2: i830_write_fence_reg(dev, reg, obj); break;
+ default: break;
+ }
}
static int
@@ -2447,24 +2468,8 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
update:
obj->tiling_changed = false;
- switch (INTEL_INFO(dev)->gen) {
- case 7:
- case 6:
- ret = sandybridge_write_fence_reg(obj);
- break;
- case 5:
- case 4:
- ret = i965_write_fence_reg(obj);
- break;
- case 3:
- ret = i915_write_fence_reg(obj);
- break;
- case 2:
- ret = i830_write_fence_reg(obj);
- break;
- }
-
- return ret;
+ i915_gem_write_fence(dev, reg - dev_priv->fence_regs, obj);
+ return 0;
}
/**
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 08/12] drm/i915: Refactor put_fence() to use the common fence writing routine
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (6 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 07/12] drm/i915: Prepare to consolidate fence writing Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 09/12] drm/i915: Refactor fence clearing " Chris Wilson
` (3 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
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>
---
drivers/gpu/drm/i915/i915_gem.c | 62 ++++++++++++++++++++++++++++++++-------
1 file 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;
}
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 09/12] drm/i915: Refactor fence clearing to use the common fence writing routine
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (7 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 08/12] drm/i915: Refactor put_fence() to use the common fence writing routine Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 10/12] drm/i915: Refactor get_fence() " Chris Wilson
` (2 subsequent siblings)
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
Now that we have a routine that is able to clear the fences as well as
setup up the register for a tiled object, remove the surplus routines to
clear the fences.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 62 ++++++---------------------------------
1 file changed, 9 insertions(+), 53 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3601b8b..e09ac3a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -42,8 +42,6 @@ static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *o
static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
unsigned alignment,
bool map_and_fenceable);
-static void i915_gem_clear_fence_reg(struct drm_device *dev,
- struct drm_i915_fence_reg *reg);
static int i915_gem_phys_pwrite(struct drm_device *dev,
struct drm_i915_gem_object *obj,
struct drm_i915_gem_pwrite *args,
@@ -1655,19 +1653,18 @@ static void i915_gem_reset_fences(struct drm_device *dev)
for (i = 0; i < dev_priv->num_fence_regs; i++) {
struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
- struct drm_i915_gem_object *obj = reg->obj;
- if (!obj)
- continue;
+ i915_gem_write_fence(dev, i, NULL);
- if (obj->tiling_mode)
- i915_gem_release_mmap(obj);
+ if (reg->obj)
+ i915_gem_object_fence_lost(reg->obj);
- reg->obj->fence_reg = I915_FENCE_REG_NONE;
- reg->obj->fenced_gpu_access = false;
- reg->obj->last_fenced_seqno = 0;
- i915_gem_clear_fence_reg(dev, reg);
+ reg->pin_count = 0;
+ reg->obj = NULL;
+ INIT_LIST_HEAD(®->lru_list);
}
+
+ INIT_LIST_HEAD(&dev_priv->mm.fence_list);
}
void i915_gem_reset(struct drm_device *dev)
@@ -2513,45 +2510,6 @@ update:
}
/**
- * i915_gem_clear_fence_reg - clear out fence register info
- * @obj: object to clear
- *
- * Zeroes out the fence register itself and clears out the associated
- * data structures in dev_priv and obj.
- */
-static void
-i915_gem_clear_fence_reg(struct drm_device *dev,
- struct drm_i915_fence_reg *reg)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- uint32_t fence_reg = reg - dev_priv->fence_regs;
-
- switch (INTEL_INFO(dev)->gen) {
- case 7:
- case 6:
- I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + fence_reg*8, 0);
- break;
- case 5:
- case 4:
- I915_WRITE64(FENCE_REG_965_0 + fence_reg*8, 0);
- break;
- case 3:
- if (fence_reg >= 8)
- fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4;
- else
- case 2:
- fence_reg = FENCE_REG_830_0 + fence_reg * 4;
-
- I915_WRITE(fence_reg, 0);
- break;
- }
-
- list_del_init(®->lru_list);
- reg->obj = NULL;
- reg->pin_count = 0;
-}
-
-/**
* Finds free space in the GTT aperture and binds the object there.
*/
static int
@@ -3788,9 +3746,7 @@ i915_gem_load(struct drm_device *dev)
dev_priv->num_fence_regs = 8;
/* Initialize fence registers to zero */
- for (i = 0; i < dev_priv->num_fence_regs; i++) {
- i915_gem_clear_fence_reg(dev, &dev_priv->fence_regs[i]);
- }
+ i915_gem_reset_fences(dev);
i915_gem_detect_bit_6_swizzle(dev);
init_waitqueue_head(&dev_priv->pending_flip_queue);
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 10/12] drm/i915: Refactor get_fence() to use the common fence writing routine
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (8 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 09/12] drm/i915: Refactor fence clearing " Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 11/12] drm/i915: Clarify the semantics of tiling-changed by renaming it Chris Wilson
2012-04-17 14:31 ` [PATCH 12/12] drm/i915: Only the zap the VMA after updating the tiling parameters Chris Wilson
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
We can also take advantage of the new 'no retire' mode for seqno waiting
to avoid having to take a reference on the old fence object whilst
flushing an existing fence.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 70 +++++++++++++++------------------------
1 file changed, 27 insertions(+), 43 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e09ac3a..7bc4a40 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2361,7 +2361,7 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
if (obj->last_fenced_seqno) {
ret = i915_wait_request(obj->ring,
obj->last_fenced_seqno,
- true);
+ false);
if (ret)
return ret;
@@ -2449,63 +2449,47 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
{
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ bool enable = obj->tiling_mode != I915_TILING_NONE;
struct drm_i915_fence_reg *reg;
int ret;
- if (obj->tiling_mode == I915_TILING_NONE)
- return i915_gem_object_put_fence(obj);
+ /* Have we updated the tiling parameters upon the object and so
+ * will need to serialise the write to the associated fence register?
+ */
+ if (obj->tiling_changed) {
+ ret = i915_gem_object_flush_fence(obj);
+ if (ret)
+ return ret;
+ }
/* Just update our place in the LRU if our fence is getting reused. */
if (obj->fence_reg != I915_FENCE_REG_NONE) {
reg = &dev_priv->fence_regs[obj->fence_reg];
- list_move_tail(®->lru_list, &dev_priv->mm.fence_list);
+ if (!obj->tiling_changed) {
+ list_move_tail(®->lru_list,
+ &dev_priv->mm.fence_list);
+ return 0;
+ }
+ } else if (enable) {
+ reg = i915_find_fence_reg(dev);
+ if (reg == NULL)
+ return -EDEADLK;
+
+ if (reg->obj) {
+ struct drm_i915_gem_object *old = reg->obj;
- if (obj->tiling_changed) {
- ret = i915_gem_object_flush_fence(obj);
+ ret = i915_gem_object_flush_fence(old);
if (ret)
return ret;
- goto update;
+ i915_gem_object_fence_lost(old);
}
-
+ } else
return 0;
- }
-
- reg = i915_find_fence_reg(dev);
- if (reg == NULL)
- return -EDEADLK;
-
- ret = i915_gem_object_flush_fence(obj);
- if (ret)
- return ret;
-
- if (reg->obj) {
- struct drm_i915_gem_object *old = reg->obj;
- drm_gem_object_reference(&old->base);
-
- if (old->tiling_mode)
- i915_gem_release_mmap(old);
-
- ret = i915_gem_object_flush_fence(old);
- if (ret) {
- drm_gem_object_unreference(&old->base);
- return ret;
- }
-
- old->fence_reg = I915_FENCE_REG_NONE;
- old->last_fenced_seqno = 0;
-
- drm_gem_object_unreference(&old->base);
- }
-
- reg->obj = obj;
- list_move_tail(®->lru_list, &dev_priv->mm.fence_list);
- obj->fence_reg = reg - dev_priv->fence_regs;
-
-update:
+ i915_gem_object_update_fence(obj, reg, enable);
obj->tiling_changed = false;
- i915_gem_write_fence(dev, reg - dev_priv->fence_regs, obj);
+
return 0;
}
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 11/12] drm/i915: Clarify the semantics of tiling-changed by renaming it
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (9 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 10/12] drm/i915: Refactor get_fence() " Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
2012-04-18 12:05 ` Daniel Vetter
2012-04-17 14:31 ` [PATCH 12/12] drm/i915: Only the zap the VMA after updating the tiling parameters Chris Wilson
11 siblings, 1 reply; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
Rename obj->tiling_changed to obj->fence_change so that it is clear that
it flags when the parameters for an active fence (including the
no-fence) register are changed.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 7 ++++++-
drivers/gpu/drm/i915/i915_gem.c | 8 ++++----
drivers/gpu/drm/i915/i915_gem_tiling.c | 5 ++++-
3 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8c32ada..3d7ad9b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -869,7 +869,12 @@ struct drm_i915_gem_object {
* Current tiling mode for the object.
*/
unsigned int tiling_mode:2;
- unsigned int tiling_changed:1;
+ /**
+ * Whether the tiling parameters for the currently associated fence
+ * register have changed. Note that for the purposes of tracking
+ * tiling changes we also treat the unfenced register as a "fence".
+ */
+ unsigned int fence_changed:1;
/** How many users have pinned this object in GTT space. The following
* users can each hold at most one reference: pwrite/pread, pin_ioctl
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7bc4a40..5edab3f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -66,7 +66,7 @@ static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *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_changed = false;
obj->fence_reg = I915_FENCE_REG_NONE;
}
@@ -2456,7 +2456,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
/* Have we updated the tiling parameters upon the object and so
* will need to serialise the write to the associated fence register?
*/
- if (obj->tiling_changed) {
+ if (obj->fence_changed) {
ret = i915_gem_object_flush_fence(obj);
if (ret)
return ret;
@@ -2465,7 +2465,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
/* Just update our place in the LRU if our fence is getting reused. */
if (obj->fence_reg != I915_FENCE_REG_NONE) {
reg = &dev_priv->fence_regs[obj->fence_reg];
- if (!obj->tiling_changed) {
+ if (!obj->fence_changed) {
list_move_tail(®->lru_list,
&dev_priv->mm.fence_list);
return 0;
@@ -2488,7 +2488,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
return 0;
i915_gem_object_update_fence(obj, reg, enable);
- obj->tiling_changed = false;
+ obj->fence_changed = false;
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 1a93066..e51d892 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -374,7 +374,10 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
}
if (ret == 0) {
- obj->tiling_changed = true;
+ obj->fence_changed =
+ obj->fenced_gpu_access ||
+ obj->fence_reg != I915_FENCE_REG_NONE;
+
obj->tiling_mode = args->tiling_mode;
obj->stride = args->stride;
}
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 12/12] drm/i915: Only the zap the VMA after updating the tiling parameters
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
` (10 preceding siblings ...)
2012-04-17 14:31 ` [PATCH 11/12] drm/i915: Clarify the semantics of tiling-changed by renaming it Chris Wilson
@ 2012-04-17 14:31 ` Chris Wilson
11 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-17 14:31 UTC (permalink / raw)
To: intel-gfx
If we fail to unbind and so abort the change in tiling, we will have
removed the VMA for the object for no reason. The likelihood of unbind
failing is slim (other than ERESTARTSYS which will cause userspace to
try again), so the change is mostly for the principle.
Also improve the slightly stale comment.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem_tiling.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index e51d892..6a2bd54 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -354,9 +354,10 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
/* We need to rebind the object if its current allocation
* no longer meets the alignment restrictions for its new
* tiling mode. Otherwise we can just leave it alone, but
- * need to ensure that any fence register is cleared.
+ * need to ensure that any fence register is updated before
+ * the next fenced (either through the GTT or by the BLT unit
+ * on older GPUs) access.
*/
- i915_gem_release_mmap(obj);
obj->map_and_fenceable =
obj->gtt_space == NULL ||
@@ -380,6 +381,9 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
obj->tiling_mode = args->tiling_mode;
obj->stride = args->stride;
+
+ /* Force the fence to be reacquired for GTT access */
+ i915_gem_release_mmap(obj);
}
}
/* we have to maintain this existing ABI... */
--
1.7.10
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 11/12] drm/i915: Clarify the semantics of tiling-changed by renaming it
2012-04-17 14:31 ` [PATCH 11/12] drm/i915: Clarify the semantics of tiling-changed by renaming it Chris Wilson
@ 2012-04-18 12:05 ` Daniel Vetter
2012-04-18 12:12 ` Chris Wilson
0 siblings, 1 reply; 15+ messages in thread
From: Daniel Vetter @ 2012-04-18 12:05 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx
On Tue, Apr 17, 2012 at 03:31:34PM +0100, Chris Wilson wrote:
> Rename obj->tiling_changed to obj->fence_change so that it is clear that
> it flags when the parameters for an active fence (including the
> no-fence) register are changed.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
I've picked up all the patches for -next up to this one. Thanks a lot for
cleaning out the cruft here. For this patch I've got a bit confused about
fence_changed. Chris suggested fence_dirty on irc and I like it.
-Daniel
> ---
> drivers/gpu/drm/i915/i915_drv.h | 7 ++++++-
> drivers/gpu/drm/i915/i915_gem.c | 8 ++++----
> drivers/gpu/drm/i915/i915_gem_tiling.c | 5 ++++-
> 3 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8c32ada..3d7ad9b 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -869,7 +869,12 @@ struct drm_i915_gem_object {
> * Current tiling mode for the object.
> */
> unsigned int tiling_mode:2;
> - unsigned int tiling_changed:1;
> + /**
> + * Whether the tiling parameters for the currently associated fence
> + * register have changed. Note that for the purposes of tracking
> + * tiling changes we also treat the unfenced register as a "fence".
> + */
> + unsigned int fence_changed:1;
>
> /** How many users have pinned this object in GTT space. The following
> * users can each hold at most one reference: pwrite/pread, pin_ioctl
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 7bc4a40..5edab3f 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -66,7 +66,7 @@ static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *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_changed = false;
> obj->fence_reg = I915_FENCE_REG_NONE;
> }
>
> @@ -2456,7 +2456,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
> /* Have we updated the tiling parameters upon the object and so
> * will need to serialise the write to the associated fence register?
> */
> - if (obj->tiling_changed) {
> + if (obj->fence_changed) {
> ret = i915_gem_object_flush_fence(obj);
> if (ret)
> return ret;
> @@ -2465,7 +2465,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
> /* Just update our place in the LRU if our fence is getting reused. */
> if (obj->fence_reg != I915_FENCE_REG_NONE) {
> reg = &dev_priv->fence_regs[obj->fence_reg];
> - if (!obj->tiling_changed) {
> + if (!obj->fence_changed) {
> list_move_tail(®->lru_list,
> &dev_priv->mm.fence_list);
> return 0;
> @@ -2488,7 +2488,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
> return 0;
>
> i915_gem_object_update_fence(obj, reg, enable);
> - obj->tiling_changed = false;
> + obj->fence_changed = false;
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
> index 1a93066..e51d892 100644
> --- a/drivers/gpu/drm/i915/i915_gem_tiling.c
> +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
> @@ -374,7 +374,10 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
> }
>
> if (ret == 0) {
> - obj->tiling_changed = true;
> + obj->fence_changed =
> + obj->fenced_gpu_access ||
> + obj->fence_reg != I915_FENCE_REG_NONE;
> +
> obj->tiling_mode = args->tiling_mode;
> obj->stride = args->stride;
> }
> --
> 1.7.10
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Mail: daniel@ffwll.ch
Mobile: +41 (0)79 365 57 48
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 11/12] drm/i915: Clarify the semantics of tiling-changed by renaming it
2012-04-18 12:05 ` Daniel Vetter
@ 2012-04-18 12:12 ` Chris Wilson
0 siblings, 0 replies; 15+ messages in thread
From: Chris Wilson @ 2012-04-18 12:12 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
On Wed, 18 Apr 2012 14:05:02 +0200, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Tue, Apr 17, 2012 at 03:31:34PM +0100, Chris Wilson wrote:
> > Rename obj->tiling_changed to obj->fence_change so that it is clear that
> > it flags when the parameters for an active fence (including the
> > no-fence) register are changed.
> >
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
>
> I've picked up all the patches for -next up to this one. Thanks a lot for
> cleaning out the cruft here. For this patch I've got a bit confused about
> fence_changed. Chris suggested fence_dirty on irc and I like it.
I'm working on improving the comments here which will impact this and
the next patch...
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2012-04-18 12:12 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-17 14:31 Kill unused fence pipelining Chris Wilson
2012-04-17 14:31 ` [PATCH 01/12] drm/i915: Remove the pipelined parameter from get_fence() Chris Wilson
2012-04-17 14:31 ` [PATCH 02/12] drm/i915: Remove fence pipelining Chris Wilson
2012-04-17 14:31 ` [PATCH 03/12] drm/i915: Remove unused ring->setup_seqno Chris Wilson
2012-04-17 14:31 ` [PATCH 04/12] drm/i915: Discard the unused obj->last_fenced_ring Chris Wilson
2012-04-17 14:31 ` [PATCH 05/12] drm/i915: Simplify fence finding Chris Wilson
2012-04-17 14:31 ` [PATCH 06/12] drm/i915: Remove the unsightly "optimisation" from flush_fence() Chris Wilson
2012-04-17 14:31 ` [PATCH 07/12] drm/i915: Prepare to consolidate fence writing Chris Wilson
2012-04-17 14:31 ` [PATCH 08/12] drm/i915: Refactor put_fence() to use the common fence writing routine Chris Wilson
2012-04-17 14:31 ` [PATCH 09/12] drm/i915: Refactor fence clearing " Chris Wilson
2012-04-17 14:31 ` [PATCH 10/12] drm/i915: Refactor get_fence() " Chris Wilson
2012-04-17 14:31 ` [PATCH 11/12] drm/i915: Clarify the semantics of tiling-changed by renaming it Chris Wilson
2012-04-18 12:05 ` Daniel Vetter
2012-04-18 12:12 ` Chris Wilson
2012-04-17 14:31 ` [PATCH 12/12] drm/i915: Only the zap the VMA after updating the tiling parameters Chris Wilson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox